|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,9 g* ~2 t- V, u/ |, F! q' y
/ N+ G# f6 ^, \; N! l
, p* I8 T8 ]' r/ j///////////////////////////////////////////
% s0 A+ h( @7 w3 M//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.; n& n' A/ D* r
. l( V M) |, w Y2 M2 }( B5 L" U6 P
#pragma once
1 A" L- t a O4 N#include <exception>* ^* y ?( O' j' ~0 i3 [3 `
% K( Q) R9 F0 `: ?; O; R/ I
, x% X( @0 \- V enum TRISTATE{* L2 Y5 V2 f/ W) t# f; |; y
TRIS_FALSE,2 Q5 q% _ Q5 u
TRIS_UNKNOWN,
/ F/ x. u# l. B& D TRIS_TRUE
E4 y6 o8 X9 X. J( v};( ]* i5 M b, G' i" M) |) W
1 I$ ?+ h# W1 U1 y) n; ^: E
# Z; m+ p3 a9 y+ _' p: r
enum UPNP_IMPLEMENTATION{ e0 L# G# o2 }+ J7 _9 u
UPNP_IMPL_WINDOWSERVICE = 0,
" b0 C) `1 {, T: h3 ~# X2 s UPNP_IMPL_MINIUPNPLIB,
; G0 S/ T7 \7 [ UPNP_IMPL_NONE /*last*/4 v# ]3 l0 u( X) L
};% F, G: d. W) @ [: |( H5 K
- v2 R I1 J# ^( |6 Y% {# W( N$ b, [1 ] F$ w+ }
3 C: k D5 G; m( Z3 x% z; G* x& h& ?8 o8 ]1 A4 S
class CUPnPImpl0 M, {/ z% b6 F- m3 c" U, O
{% F8 U% j1 D( j8 N1 G9 f8 [0 }
public:
3 X; o8 z( y7 R: d# W3 w) e& V9 A CUPnPImpl();
4 p3 ~# _; s9 Y: F8 |+ a* C+ e) B virtual ~CUPnPImpl();
) j3 Q2 `% ?8 |1 f& x: F struct UPnPError : std::exception {};5 B/ W% B/ T0 |3 v R5 Y
enum {8 o/ a, }& v# c% X3 D. ^0 B
UPNP_OK, B5 f% ?2 A$ }0 w# L
UPNP_FAILED,( i @# m0 B* o* f( g' H0 k1 H5 m
UPNP_TIMEOUT7 S1 K$ j6 y/ _, H/ p4 _- L
};1 o0 ~ Q: o! @3 E2 K; z
5 B1 R& g6 T8 `0 V: q U
- E$ G& O9 H- X0 y2 T, x% ^/ B virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
; }% ~1 b9 _. p6 o9 U+ q virtual bool CheckAndRefresh() = 0;8 Y2 f8 G3 w+ i# ~ q, {
virtual void StopAsyncFind() = 0;. z2 ?5 I$ R: n0 J% Y
virtual void DeletePorts() = 0;: [; |( x! O. ^( E2 l5 I8 B9 ]) W' `
virtual bool IsReady() = 0;
6 H; A# X3 [" d$ W, G virtual int GetImplementationID() = 0;, \ v3 L, y1 p$ |
0 k6 W3 L( [* T3 |$ C void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping7 f P7 Q$ V9 U1 U
, U& ^: _ S6 |2 b! R9 S
, |$ |) D" Z+ ~( ^; |6 z7 {/ W1 O void SetMessageOnResult(HWND hWindow, UINT nMessageID);5 j( j4 O* j: Q! W% U
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }5 m& _ j# r1 |& J! C, g3 J
uint16 GetUsedTCPPort() { return m_nTCPPort; }( g; R% N! z5 i5 N
uint16 GetUsedUDPPort() { return m_nUDPPort; } . K% `4 {0 b D$ |
0 r: H X; @. C7 j: C8 C$ t k& y7 l/ ~" f% G V; _
// Implementation
# f9 ]4 d& d' {" c. E- A% Mprotected:
" g) h m" X! f volatile TRISTATE m_bUPnPPortsForwarded;) M# G& \: w1 F- O4 I, l
void SendResultMessage();
9 T: ^2 @- j! p" s1 L uint16 m_nUDPPort;9 O1 b) W( }" f8 W
uint16 m_nTCPPort;
% I4 e0 Q" m6 g6 p: f/ O uint16 m_nTCPWebPort;( ^* Y" j- ?+ A3 t, }9 P: b
bool m_bCheckAndRefresh;
9 `& d& s' b9 ^) x6 e) X! G1 B- V7 b p
. M2 t- b3 @7 z6 x; \4 [: j, hprivate:
8 Z3 l% h8 r6 I* ^9 E5 k HWND m_hResultMessageWindow;! Z- N5 r* ?; L# a) r4 E j& w; g/ ?/ \
UINT m_nResultMessageID;+ [1 r1 {7 ?( Z1 z3 \% J
/ y" A, g- a/ b$ J% x8 U0 x! h0 X
0 t2 W! d0 Q7 m. b+ U};
9 d0 K; Z. {; ~3 \ Y$ W# W8 E; k# Y2 _
\) u9 P7 u: y$ t5 c// Dummy Implementation to be used when no other implementation is available3 w$ J5 k/ {% i1 m
class CUPnPImplNone: public CUPnPImpl
! V g' s1 h6 w8 h2 ]6 K5 l' }! E{
7 X2 d+ ?$ g# jpublic:8 Q2 V4 P: b6 b! ~
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }) n0 b7 \, h1 U
virtual bool CheckAndRefresh() { return false; }
4 ` O! z/ Q9 S2 u% a virtual void StopAsyncFind() { }5 P+ Y2 D. N6 d+ \$ y2 E
virtual void DeletePorts() { }; P$ R% y. _ k! F+ s* f4 p% f& M
virtual bool IsReady() { return false; }- m/ i/ x8 J1 s2 b2 s% @
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
( d _1 | q+ R( y};# [6 Z' R% |) g$ a* b2 L$ W
2 y" W5 T5 Z) ~2 A- F& Y4 v5 [1 z7 l/ w& U
/////////////////////////////////////& I1 ?7 @/ W6 z& z) J2 s! X
//下面是使用windows操作系统自带的UPNP功能的子类% m: t6 A: V/ m4 n
3 R4 B: q9 `1 c3 b6 Q, L* T, F3 P5 x/ p5 x
#pragma once* h. [5 B2 r) ]6 p+ \3 p: S
#pragma warning( disable: 4355 )
; |7 X+ x* U/ u4 Y" n7 }. v2 ^
/ K0 K% |4 k" b) `! Z* b5 c0 Z; x* M8 O" K) Q- \# a% O( X' @
#include "UPnPImpl.h"
) g* l5 [4 I6 M3 e#include <upnp.h>9 h" [: x: p8 K, G8 F( m
#include <iphlpapi.h>* o6 n& W8 \; S- A" G( ~: y
#include <comdef.h>
% Y7 |+ c3 B+ i) q n3 Q) N2 V#include <winsvc.h>
. B* w: ^& s# l5 G; z
7 y' w$ U1 ]- o+ b1 w7 K- A9 `
% w( Z8 | P8 N* `' O#include <vector>
0 f7 F! j! B" [# W#include <exception>
8 k- V& G' x/ f' T H#include <functional># |3 y6 ^" i& l1 X" @- r
- H0 r" r- P9 k. C9 ^
3 _$ m, F# x! e$ {- o
' x# c* [8 c8 Z5 X
. {5 e- [# I, q/ {7 H- Etypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;" G: e: ?/ _3 S4 d G! E5 h; _ }
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
; v* _' x7 q1 ctypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;! e/ K/ O- L5 N0 H" U
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;" v2 `/ w/ ^" Q) F/ R5 n- R
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;9 m! t+ K+ e+ u) L3 P5 s
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
' B5 s) U' d: o3 d" }typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
/ h3 w, S0 `6 O& P& P/ `, l+ P
3 n5 [) K' O# T4 K3 M1 j+ T9 x# U! k% T* }. f6 _2 L; @
typedef DWORD (WINAPI* TGetBestInterface) (
4 N" R' k L/ Y IPAddr dwDestAddr,1 ]) o/ M" Q y3 ~" k
PDWORD pdwBestIfIndex% A6 x# I- W, F! d+ D) z0 ?8 @
);
1 ^; o6 t# R% h$ V7 S" o9 z
- W, _* n/ I" G2 O2 ~" ~4 q) F* i% A& n2 e) b' f9 Y4 _
typedef DWORD (WINAPI* TGetIpAddrTable) (' D0 F; T9 Z: i- U5 V8 T" u
PMIB_IPADDRTABLE pIpAddrTable,
- q7 E0 S" m+ q/ y. W+ W% F PULONG pdwSize,
$ q$ [) M9 ~2 U BOOL bOrder5 M# I% p" U4 m9 @7 i' B/ l8 b9 U2 R
);. q" B: Y6 `) Y y+ O; I. r
1 Z9 n% R6 b/ x6 N# ~) W, o' Q$ s ~* {$ z2 _" k/ y6 O
typedef DWORD (WINAPI* TGetIfEntry) (
- h6 V0 L% i; j, Q- e* E PMIB_IFROW pIfRow
9 D2 n+ W2 D0 e& P);
8 e) N' P: H5 g0 P1 e8 z1 `
! p u6 s" ^! W7 D8 v j6 W6 Y9 ^' _1 C4 D: a% @
CString translateUPnPResult(HRESULT hr);
4 O& @$ ~8 v) _$ u% Z! W* V8 m! zHRESULT UPnPMessage(HRESULT hr);6 l( ?. [, d0 ` }3 c) Y+ F) @* B
# {$ `% y' J. t' j7 [, O$ x
8 s* ], X' t) j; _3 K$ mclass CUPnPImplWinServ: public CUPnPImpl
6 [% p8 y8 ]! T7 g( i$ e0 N2 I, {2 r{* s6 H- C/ M6 g7 t" v( ~
friend class CDeviceFinderCallback;! u ~3 r% S5 q& Y. ]
friend class CServiceCallback;: {& m) I. A3 Q, n
// Construction1 u: w# q0 U, e& C' B
public:
: h4 v- h2 N2 O: b1 F$ |* C9 J virtual ~CUPnPImplWinServ();' @( l: l9 i+ ?# i
CUPnPImplWinServ();. h8 Z% @& S; \" |2 C) c2 r; d: r
9 }5 m6 }/ ]7 I' R$ ?& f& a& b1 \
1 C% F8 W0 u; D2 E$ g" o- H; m( ^ virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
8 [/ T+ x2 D' E4 n6 J8 j& ~' u* D virtual void StopAsyncFind();( H# \& U4 O! x" K( _3 V A9 l
virtual void DeletePorts();; m& F4 q) \' @) r. K7 g, L
virtual bool IsReady();
$ _9 g, K- M# K0 }3 @ virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }) A* b- T0 x0 i
% ^3 U! U0 s, {9 X, u# a- G
2 p$ ~' a+ \ f+ J$ B
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
1 q7 Y9 V# T6 m9 K& g j // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later" p9 Q$ q2 ~) C4 S9 |3 u% L) T
virtual bool CheckAndRefresh() { return false; };! E' J' W$ v, P* C* {
# W2 \- U2 `( `7 W+ K! a
. N+ S1 A; N8 C) s# h* ~( t
protected:8 Z; @' V2 B1 {2 P$ z) A. o
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
; F3 k+ i8 V. T+ |) E' Y void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
- E; D! o& R/ I2 V: M void RemoveDevice(CComBSTR bsUDN);+ o" J$ {3 |$ C6 U' b+ m7 Y- i
bool OnSearchComplete();; ^3 h* P1 x1 X5 O2 n, _3 L
void Init();! g5 h$ U, B! o
7 ]8 s1 N& Z: V3 r
: }' h3 q8 O5 M5 u inline bool IsAsyncFindRunning()
9 n- X, \# I, N4 b) ]! Y" y5 ~ {' \8 K2 u$ W& J/ `% `: N8 I
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
( K7 D! l8 [$ o% t; R* U+ w {. q, g! |2 a2 i2 S9 n
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );0 E( E9 D3 G5 ?, Z; O
m_bAsyncFindRunning = false;
* G2 Y/ l1 y- d }5 b T, D* A& p7 L6 s, y ~9 M
MSG msg;
2 n3 q4 q( s3 C. c/ A2 X S1 m; j! f' V6 w while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
5 \; Y( N4 f- k! f* i* r { ]$ l& C& v% |/ d4 R
TranslateMessage( &msg );; @) f2 `" S7 x5 y; C6 F
DispatchMessage( &msg );5 w* R; R9 J) S: k
}2 c) m3 E& ?; H& Z5 e% b
return m_bAsyncFindRunning;3 J- a* I! r! s! {7 C3 ?- z
}3 h8 h8 c- w) P0 V0 D. B* K' g Q
$ ~1 i% F& t) n0 T8 p
: |: i8 _7 B1 p0 ?& H4 V1 i TRISTATE m_bUPnPDeviceConnected;
' E" I- b) w, q F- U- k" y/ G8 `' `1 `! N0 |* X# b1 p7 d% I& O
% I8 m5 e5 o w" n1 \. n2 r# ~
// Implementation$ `4 P9 s1 P; ^6 Q
// API functions
* }1 N$ W6 E- Y SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);! E" @1 I4 `9 c$ d# n* k
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
% I p* h- k; [8 d0 [ BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
# ?# Q K* _" ?( t7 U9 x7 G BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
' N* x8 V1 o! W! F9 m$ N& [% ~ BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
/ ^# F, d& z9 h BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
+ K) \' u3 u% z7 \7 [3 x
& | F G7 X0 ^; S. q+ W o; g% Y5 m0 v% n
TGetBestInterface m_pfGetBestInterface;0 r8 h: U# _+ Z0 a
TGetIpAddrTable m_pfGetIpAddrTable;
( I$ [; a5 S1 R TGetIfEntry m_pfGetIfEntry;
: }- |2 f; n/ ]* c, `' @; E: |0 M0 F% @# q- Y) H
& ?5 f9 C! d6 ^% e
static FinderPointer CreateFinderInstance();: O4 x; F+ C* m" @
struct FindDevice : std::unary_function< DevicePointer, bool >; V* g- t d! B L% f
{
6 ]' n/ }4 Y8 e C3 e' h m% z FindDevice(const CComBSTR& udn) : m_udn( udn ) {} ^3 [2 b: t+ \1 u' U
result_type operator()(argument_type device) const3 i, P( t5 r2 n) a) E- \
{
0 z7 I( P5 W' ]3 C1 F CComBSTR deviceName;% d; D& u' x2 J: Y
HRESULT hr = device->get_UniqueDeviceName( &deviceName );/ S5 ^' @/ T6 T0 @6 U1 _
8 l' H* K8 D1 V; |" G* o
7 @ a2 t8 L b
if ( FAILED( hr ) )( `( D/ T% T" M z% T8 X, U
return UPnPMessage( hr ), false;
* } |: U/ o5 A. l
8 ?- o8 ?0 y m- w" O0 P* r2 R# F) q& ~+ w: ]5 d$ B
return wcscmp( deviceName.m_str, m_udn ) == 0;8 G, u7 f" W& ~+ U
}
0 f+ b- d) t f CComBSTR m_udn;
3 u3 D9 w- m' ~$ A5 W };2 s' a; i5 B% }/ ~% D$ V
. {9 N# R+ l9 J1 d0 H void ProcessAsyncFind(CComBSTR bsSearchType);+ T1 {' c* l+ @" `" `
HRESULT GetDeviceServices(DevicePointer pDevice);" b$ }! \3 {0 ?0 G, V& i8 Z
void StartPortMapping();
- e1 m$ M5 n2 b) w HRESULT MapPort(const ServicePointer& service);6 N2 D" d2 ^; @
void DeleteExistingPortMappings(ServicePointer pService);( z. ]" _3 k: ~/ N8 K; t! j
void CreatePortMappings(ServicePointer pService);# V! T T. h4 U! ~" P: B
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);, ]% ?. |* G- G* f8 ^. N$ r, Y( N0 M
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
$ K7 J" A# t0 P. S: E) x1 P; ^ LPCTSTR pszInArgString, CString& strResult);
- Y, u3 c% o) K6 w" ^ void StopUPnPService();, i* Z6 ^0 W' h- ~6 X
5 j$ p0 X5 ?4 k/ d1 X
; g1 M5 ]( Y) m7 [- E. Z$ T // Utility functions* C4 y C6 Y# |2 P
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);. X8 _! k4 S' _( {1 v' h
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);2 g5 o4 |& `& X4 O3 v. ]
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);+ a# c4 d: R+ L# a, E
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
. ^- O6 [/ }8 k0 ^3 Q HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
7 O7 Z7 E+ ?5 X HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);5 c) v9 A. v3 |! }) D e" k
CString GetLocalRoutableIP(ServicePointer pService);) T, J" j- L) u/ r4 e
: W3 [' G4 ?) |9 R0 v5 c' f8 C, N g" U' W
// Private members8 P; F( v4 `- q- R1 }
private:' ]4 e3 {% \0 p
DWORD m_tLastEvent; // When the last event was received?
1 {9 U7 ]2 F! r& s# c std::vector< DevicePointer > m_pDevices;# m D0 m2 s8 X% t- j! k+ F
std::vector< ServicePointer > m_pServices;
$ P+ R2 g3 q# Z8 R1 \, J5 r FinderPointer m_pDeviceFinder;
) N4 V) v# a( t* Y DeviceFinderCallback m_pDeviceFinderCallback;
4 ^+ M9 u \) \+ P ServiceCallback m_pServiceCallback;, J7 t- y- V9 E# D
7 Y. V! @ y8 ]7 b4 `
2 ~3 F, p/ Q. u, U LONG m_nAsyncFindHandle;
7 P+ f- y* I2 t) f: E6 G bool m_bCOM;
. ~ p; D6 b" W bool m_bPortIsFree;" W' \4 u0 l) g) m/ X
CString m_sLocalIP;
( w) H! T9 `! @' }" ]* p CString m_sExternalIP;5 b; L, W3 p# {' H9 @: P
bool m_bADSL; // Is the device ADSL?' [' z1 K! j2 D
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
2 ~! V. p: f( K1 w: }7 O# Z bool m_bInited;
/ K% b/ s# {: e- K E9 ]$ Z! v( X bool m_bAsyncFindRunning;
/ T8 `' u) N3 r HMODULE m_hADVAPI32_DLL;
/ i' y1 M8 V4 z HMODULE m_hIPHLPAPI_DLL;; g! B, ^; _3 T) T
bool m_bSecondTry;
! o7 Q) ?$ W7 K" _0 `, s/ { bool m_bServiceStartedByEmule;
9 x, `. }4 H) L3 k9 }- L bool m_bDisableWANIPSetup;
( V, ~ Z% j) Z1 A' N( ?, e9 | bool m_bDisableWANPPPSetup;& i& [+ ]; K% @
# d( |- _, J( x0 \2 a* h8 c
: d1 k/ E4 a/ |- ~* X% f) W
};
) U' b* y0 i( ?/ l( F# k/ b$ `2 m
" A4 o1 s4 O6 A. p/ t/ F- |4 D$ D* G2 R v/ D
// DeviceFinder Callback
# [& H# P2 |3 k4 {# P: g8 g" Z# cclass CDeviceFinderCallback1 H# d1 Q3 W; i/ V' ?4 s: T/ X* q) u2 s
: public IUPnPDeviceFinderCallback. V& T4 p& n8 C2 Y7 ^# l, a
{0 d& D0 I$ F9 A3 A% N Z
public:
. |& ~; [( p, z6 c) |" N5 k# t6 c% u CDeviceFinderCallback(CUPnPImplWinServ& instance)
" P3 u6 ?; ]8 V+ C( I : m_instance( instance )
# M+ A- F d; T% X" e { m_lRefCount = 0; }
* k7 u( p5 e7 J) h3 H2 \- J; s, J! U/ a4 Y
4 Z8 S, w' ^0 E3 t6 A STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);1 Z( G" K i3 N6 z4 {. f1 D
STDMETHODIMP_(ULONG) AddRef();: q e4 i8 {/ n, e) c8 b8 p
STDMETHODIMP_(ULONG) Release();( {5 K. q \+ a. W* D1 X- z
5 B+ c6 G) } a
$ V2 m& w1 B, e1 V! r5 D% @( h// implementation
2 Y" ?2 B7 `6 i! V- s) {( L- ?1 C$ tprivate:/ Y5 @7 B& F5 l( W: t5 J+ K6 Q
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
& K3 T# Z F1 }- e HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
% f" Z7 Z: c: j8 E HRESULT __stdcall SearchComplete(LONG nFindData);
/ u1 k% {; h$ y" N, L+ o
) d6 a" w; g7 W( @8 ^, b* K8 l8 C8 @, g6 ]5 p$ t7 b1 r
private:* u1 M- T C& `$ n, b/ S
CUPnPImplWinServ& m_instance;( ?/ D7 i: O* S# o0 u; z
LONG m_lRefCount;$ ~* v1 k [: q5 G4 v" a0 H
};
1 D. r7 |- j! Y& w# @2 F P% R0 Z$ d# B( O0 k
1 q' H5 C; S. H' W a; [$ y% @3 y' V
// Service Callback
) \8 w) S# C7 v( ~class CServiceCallback8 Y1 D! P( m0 `- I h1 `( f
: public IUPnPServiceCallback
z! S9 V* \' m" p5 N2 S, M{
* r) p1 [+ P: D8 Lpublic:8 i9 o, N6 t5 o2 P3 R% [
CServiceCallback(CUPnPImplWinServ& instance)
: Y! W, T$ {% F- | : m_instance( instance )
6 z; H: M/ y, }3 Z/ e% Q& u { m_lRefCount = 0; }
- i: e& U& A8 w( B) q 3 |) G5 y8 W8 Z, o. \
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);" E6 }. O2 r0 L- l1 }
STDMETHODIMP_(ULONG) AddRef();
; M' j" u% E& Z; \/ o STDMETHODIMP_(ULONG) Release();
5 G2 F$ H$ \* O* r2 E. R4 R8 s2 w
# ?# u. \0 T5 F6 D: o/ o7 ]+ H( z+ J# U) r1 K& S8 N( D5 S4 L
// implementation; I* h5 f1 h8 ^0 x! |- s. P
private:
2 \* ~1 |3 H; q& f V) [# F HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);9 p- K8 }* g* G
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);3 E& r2 X, s- ^* Z
4 `2 b. D" `2 e6 T- M: T. @
6 g: V# M3 C( \4 hprivate:9 T0 S Q& U+ T- Y L& X: m
CUPnPImplWinServ& m_instance;
4 f8 E3 B) G. i2 Y. H0 t( E LONG m_lRefCount;
" s! j9 x3 e: N+ F, A1 a) o};
4 v# R+ E# U4 o7 r3 s6 F: ~- d1 I# U1 l
* F" F. }( _* m" n7 D7 e) E+ J/ S/////////////////////////////////////////////////
, Z( |2 L8 o5 k* K* B6 h2 S2 O; r
# w) [% H) A4 u+ ]
8 q* ^7 ~/ W' I$ P; L# [使用时只需要使用抽象类的接口。
% d; z* z$ o6 i O3 q% f8 ]. cCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
3 y5 t" a! Y& a0 U1 YCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
) I2 |# ]& L6 O' \! Z! s* [CUPnPImpl::StopAsyncFind停止设备查找.# Z) B& ^9 _! i" n
CUPnPImpl::DeletePorts删除端口映射. |
|