|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
9 D0 [. w6 c' [7 t3 r( ?6 r
2 ^; M, y/ Q. c4 m: P/ a. q7 t1 q$ F8 s" o
///////////////////////////////////////////
4 ]0 y7 k9 G, o; n7 k//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.# i* Y- [2 j2 M4 F, w4 _
' H0 \; n3 I3 z5 f; `% y# r% ?
+ K+ w) w! r: n! t4 \: j#pragma once! N4 |2 }% m3 j: n& n, {+ j+ A, X3 v
#include <exception>( T. M' }1 L J E, Y0 R$ X' y
! K! A! k. w; D5 w1 y
- `7 c! T# r3 i- F enum TRISTATE{
! q4 x$ T. O$ F$ n4 e1 H# \9 b TRIS_FALSE,
0 I) w* f5 P6 W- c! e2 U TRIS_UNKNOWN,
! W4 `5 @7 y& P! ~$ H5 l7 @ TRIS_TRUE! G& @. u6 v* q
};% o7 J) j! u% n
! q& Y1 f4 _6 R2 o" m/ \
; v- ~0 t" X% N3 e# l" G
enum UPNP_IMPLEMENTATION{0 {0 D D/ J9 G6 h3 w5 T
UPNP_IMPL_WINDOWSERVICE = 0,5 E5 J! a5 L5 ? V
UPNP_IMPL_MINIUPNPLIB,/ R# u2 I, J* e, l% ]0 p1 B
UPNP_IMPL_NONE /*last*/
% K0 z8 j' p7 y* |3 ?5 P};
" C- {& K0 G# c; n) y. D0 r+ I2 r( m8 j& K B3 p$ S; C$ h' g8 K
0 y& P/ p4 b0 W4 k6 x; E- U
, R+ f3 \0 J! i
. z( z- b( i' M9 {. iclass CUPnPImpl! Y8 }" o: A. P: H0 _
{% i4 L' w' c1 `
public:
+ s$ b/ X' u" a! }' m CUPnPImpl();! u9 u8 Y% `# j, N: ^5 u
virtual ~CUPnPImpl();
8 Z* L" l" d! F2 F9 @# v1 P3 c1 i struct UPnPError : std::exception {};3 @, K1 P5 T1 m' V
enum {
# i, M4 V& Q5 Z& S UPNP_OK,
3 T" w6 T& o/ K6 `: k: | UPNP_FAILED,
( o9 H& f( q4 m UPNP_TIMEOUT+ \: k! k* a4 i, Y: f
};
4 V: H. ?" c& h/ f# `# q
+ w4 m# i2 x# q: V: \! x
( H* C9 V; X% M1 N) t/ z0 H virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
$ d5 @0 C2 T2 K virtual bool CheckAndRefresh() = 0;
( ]# j: C4 T5 H+ k* ^5 \' S virtual void StopAsyncFind() = 0;
7 |4 H: ]! b, _ ~0 j4 C virtual void DeletePorts() = 0;. |; v6 H- |, v& S) B* d8 V( c
virtual bool IsReady() = 0;
3 ^( u* O+ J9 q6 H/ t9 l virtual int GetImplementationID() = 0;
, t5 |+ A7 q! X( B7 g/ k $ y5 e, P" X' \7 A% S: Z
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
5 f! E) O' N7 d+ O) O) Z# d
1 X) _) Y N6 V% S! F x
+ L2 C* D* |" p7 r* \ void SetMessageOnResult(HWND hWindow, UINT nMessageID);
1 @4 x* B: g# g+ s% Y TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
( E0 \# M) D2 V. B# G) U3 w uint16 GetUsedTCPPort() { return m_nTCPPort; }; \; e+ L! A0 F. s6 _3 r
uint16 GetUsedUDPPort() { return m_nUDPPort; } - K) K1 N/ A9 E: U( D
8 P6 I! S6 G5 c/ ^& i1 I- C3 f
6 ]- |1 G* X1 y" ~// Implementation! l( t4 ^7 n, ~3 N: v( i
protected:5 O6 z' X% Z) L: w+ G3 _. m
volatile TRISTATE m_bUPnPPortsForwarded;( \* g/ d# r. i; v# N" L/ ^
void SendResultMessage();1 P% D5 ~! g+ Q: D: @) u
uint16 m_nUDPPort;
/ Z1 A+ N: Q& ?6 z) p uint16 m_nTCPPort;5 L' `& B- ~7 v' j: x; Z
uint16 m_nTCPWebPort;
" r# a0 e9 m' k, T; O bool m_bCheckAndRefresh;
7 _ a1 B6 B s" l: Z% G. C! H W: A. y9 \1 \
: [8 ^% N( e9 C ~* r) L
private:/ L" N7 s4 e r' Z+ W
HWND m_hResultMessageWindow;# ` U2 X9 E1 h
UINT m_nResultMessageID;+ L2 k$ m* ~! ]
) S# v' G1 |4 D$ N9 G+ v3 P+ @; p
! R) m0 F- L4 Y2 z6 L7 I$ G};6 g/ ]; i g1 Y7 Y" b) w) x
8 @7 U$ w: q- l, {, x Z* E1 Q
4 \0 C6 R% F2 O: a4 q) V9 t# {// Dummy Implementation to be used when no other implementation is available
6 P4 e% C' V' Oclass CUPnPImplNone: public CUPnPImpl
\3 I4 m/ ^# J8 c, w: G{
" N, r( w* m8 f6 q+ e3 S* c* Bpublic:4 A4 U% e6 e* i1 \; J; U. V! L
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }; H3 [, A8 l; {6 X8 y
virtual bool CheckAndRefresh() { return false; }
+ o& \- ?, H- n* m virtual void StopAsyncFind() { }
7 [/ \! [9 I' Y+ F% N' x. |- S virtual void DeletePorts() { }' F& x4 t) C: f% e! c
virtual bool IsReady() { return false; }
% p4 ~6 S7 w$ z: f! M: @3 [ virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
0 U, ?% e5 @ y. T$ k};7 h* n$ F3 P' J$ y5 r) x: I2 i) \! T+ ^
% W9 k1 [8 [1 }: U2 I
; s: k9 R# v) Z/////////////////////////////////////
$ e% @8 u7 t! [* o//下面是使用windows操作系统自带的UPNP功能的子类5 w! {$ P, O0 ~, k( ~6 a/ q* g
o7 W+ H W n1 k) B. U: b
/ {( y+ E' K8 t7 T#pragma once
5 D, M8 }1 F! ~# E' J/ i" s#pragma warning( disable: 4355 )2 X8 ?) V6 ?5 D
?% f% A- H6 @3 j8 X! ^
I, @7 ~* [2 D) L8 E2 C; m# S9 h#include "UPnPImpl.h"( U- v6 d2 b, e) A" `( V& d
#include <upnp.h>/ x2 a/ B) }% S* y8 p
#include <iphlpapi.h>6 b9 y% a* V8 {3 ^" l
#include <comdef.h>, W7 A- b( }8 w/ @0 S
#include <winsvc.h>
" X3 l) Q+ Z( c" n0 n; p! [; I) c
* h% f- d0 x4 G8 @8 x
" b' `' u* [& {8 j5 ~5 w5 z/ J#include <vector> ~$ A( }$ V# b# D \
#include <exception>
; M# l) @: B' W9 k* b3 S#include <functional>, c" z' p( l0 q/ O
5 C" i$ D2 k; E$ @: }; m4 T
0 o' u! C9 Y" I9 v# T4 _% p" m/ }$ j1 D' Y! N
2 P8 a5 S# e: n' Z
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
, a) y, b1 z" F5 `" jtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
( y1 D1 N& R, S8 G! r8 ^typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
) m- C6 {) K O1 V+ a. rtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
( }2 c l4 E: R$ y# Itypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
2 I* M( d4 y+ P% @/ R% ]typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;5 G) T+ X% }8 ]3 T3 O
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
' r& y9 v1 D5 t0 n2 F* u$ ~6 v7 ^/ j
- @4 z$ |4 s" R0 r# [; ]
typedef DWORD (WINAPI* TGetBestInterface) (3 r9 ?; z" \0 o% u9 e$ ?1 h5 Z
IPAddr dwDestAddr," B, I" j6 z( \# s1 }. O3 y
PDWORD pdwBestIfIndex
2 R5 V V8 m) {! I/ L);! H% Q( M9 i+ M4 V6 J3 q- H" z
% v6 {% t% P5 P. O& h8 X* y0 t1 s! I/ g: X Z. ^ e
typedef DWORD (WINAPI* TGetIpAddrTable) (
' Z5 T; J5 X' Q8 \ PMIB_IPADDRTABLE pIpAddrTable,' ^: ^* d0 G% A
PULONG pdwSize," B7 }0 ]' J% q* O, ~
BOOL bOrder/ u {( b: A% B
);' F( q9 | |4 J" @0 X7 \5 \) D
8 a2 A9 W) A( i" e" k
# k1 A9 z6 ~, B$ _$ Q! R- Utypedef DWORD (WINAPI* TGetIfEntry) (6 P' ]3 X& S, ^ H2 {$ c
PMIB_IFROW pIfRow1 z( b% S/ @+ ^$ o$ v! }% F) j
);
* e+ P2 o' U9 _/ t7 [- M0 V! r: e7 h
* t1 f2 y, M& b. S* T( k% E$ e& N" a7 I- w; o
CString translateUPnPResult(HRESULT hr);, |: n. q# |# u) z6 d/ _+ v; [
HRESULT UPnPMessage(HRESULT hr);/ U- L! u( F$ x) @( y+ W+ a% |+ i
& S5 L4 j' c" ^( b( X9 F& B4 S9 E. B& q
class CUPnPImplWinServ: public CUPnPImpl
/ Z* g, m& g" U& m. V/ g$ v{
% B, ~7 d. r [: Y1 f friend class CDeviceFinderCallback;
+ C9 D- }2 I* t% Q7 `! o- @7 V/ O friend class CServiceCallback;; C: N4 p, d# K& m1 ]! g( R
// Construction: L; L4 ~- | v3 ~
public:
! M$ Q3 ?0 b, j% z0 d virtual ~CUPnPImplWinServ();$ X6 @$ ~ j9 C6 l
CUPnPImplWinServ();
7 z4 L6 p/ |5 Q& t, ]3 E
w) `4 N- o2 D% D E
* U, g& c: ]2 W2 p virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
. g4 q2 L6 a2 J virtual void StopAsyncFind();
/ T. f b* O$ M5 I) P virtual void DeletePorts();
4 U' s9 j; B7 ~; K8 V3 k virtual bool IsReady();
: i8 F1 p- L1 @ virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
! N+ M6 r; ]* u$ F) G/ L) l4 K% ^8 G& ^
8 g2 c$ _, [( q, ^! U6 a4 J/ k
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)3 ^6 e. g% B/ t
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
2 }9 d9 ]% v3 {# n virtual bool CheckAndRefresh() { return false; };
$ t( ~7 B( A! e4 N" H) F" ] N% F1 r1 k4 B% S4 v# D7 B
J9 A2 c' \# V: ^& bprotected:6 c# ~6 V) u+ J- J, P% i2 V
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
. {: i/ W+ [: }4 h. m void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);' y8 }& j9 a6 C/ K; b' d
void RemoveDevice(CComBSTR bsUDN);
$ |9 p1 u, {. h% E" h$ p bool OnSearchComplete();
; c8 t7 W$ K. B' |3 V; L void Init();
+ R0 B$ }; T( S! g5 W, @# A; f5 r9 }* z$ C6 \
( d+ m! s* [! b- L& B
inline bool IsAsyncFindRunning() ; l6 \) C5 S! ~. }
{# D& B$ g) J v+ M
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )4 ?6 F9 Y) T1 N/ ^3 |7 Q* T
{0 c/ m) {7 n: {4 @
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );4 e4 I' p' O9 ?3 p S* E+ W. N
m_bAsyncFindRunning = false;0 r& E7 E8 o: y
}1 D4 o3 h/ n& i5 s) C; Q Q
MSG msg;
3 \" Z# ]& ?8 d8 T while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
% Z: \) x) j* m6 D; t {* d1 j6 t# e" p/ }
TranslateMessage( &msg );1 Q& m! ], b) d- a( k Q& y
DispatchMessage( &msg );
A) I) Q- \% s! G9 `4 B: ] }
: v1 E' R5 L# L7 [ return m_bAsyncFindRunning;, y5 W$ h; h5 m9 S& _! s+ v
}
, C) U9 }; F0 d' B+ T- K0 P+ Q I% J7 X/ ~
, @; ^" W' z% M6 D$ W TRISTATE m_bUPnPDeviceConnected;
9 W( r8 o5 O; o7 V* \3 C) b6 K% ~- ~1 L& f9 F2 e R( v! k
; @, g" h% A9 `/ ^7 Q J0 t
// Implementation* w {% b' Y, ]8 ]" o/ q! B
// API functions
# C- {+ Y6 [* {5 M3 [ SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
7 I) }+ k' W( E# a* W% F: Z SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
! ~- F: J3 z: W! k( Q BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
+ z T t4 P1 d. s$ Z5 r. e BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
: b! i, O6 E8 F% x$ h8 k% c BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);: Z. r B* A' h1 `" b
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);' j8 ?- q W- J' R1 j
5 C* @# D8 s1 S, p$ m7 x. [0 E/ i ~
1 @2 i/ [5 k" Y- j/ d7 |. }9 I3 L TGetBestInterface m_pfGetBestInterface;* N1 j2 b# I3 O
TGetIpAddrTable m_pfGetIpAddrTable;! e7 H4 O4 j" e* h" s4 _" N y
TGetIfEntry m_pfGetIfEntry;" @. c6 S+ h# t O& @3 [. ?7 ]; Z
; p' E2 f+ `) u" a1 r1 u
# X) _/ J3 ]( u ^ m N static FinderPointer CreateFinderInstance();
) x7 M, M+ U; K8 ?" U3 X struct FindDevice : std::unary_function< DevicePointer, bool >2 u# J2 Q% U$ \3 ?: z5 N
{
4 q' J! K& p, w! [+ e FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
8 j) H% E' j5 L! \! g5 ^ result_type operator()(argument_type device) const, Q- C/ b1 ?' y4 u' F: g n' E
{5 {0 a2 t1 q5 j6 b( }3 [2 ~
CComBSTR deviceName;$ d3 J: s, i; e) J. t- P, V$ H& b
HRESULT hr = device->get_UniqueDeviceName( &deviceName );% S) \( M2 F. Z2 E2 U+ w" C
" `- ?' L* r0 Y$ X; ^ b q! K N% T9 E0 z' v: Z9 \
if ( FAILED( hr ) )
. U% i. h, K; ~! i; j0 h* M return UPnPMessage( hr ), false;3 r' e4 V# l% I2 W
9 B0 w: a# W* w3 S! g* W; q3 H7 W3 P. Z) S; {
return wcscmp( deviceName.m_str, m_udn ) == 0;
/ Y7 p" A& j: L1 E5 @0 U+ ] }6 r+ e' l! [3 z
CComBSTR m_udn;) D/ `) Y% Q K. e# N
};7 r1 Q, k0 j) i) b
2 H/ }' F/ c2 O0 [$ I void ProcessAsyncFind(CComBSTR bsSearchType);
& ^) I/ F: \" h HRESULT GetDeviceServices(DevicePointer pDevice);4 q% j7 o& M, i7 N
void StartPortMapping();0 x* ~" l! `+ |- }; r5 R, I
HRESULT MapPort(const ServicePointer& service);$ W! O% }9 t' g* _: V. }" f% C
void DeleteExistingPortMappings(ServicePointer pService);
, o2 y1 ~0 B* s7 d/ X ] I3 | void CreatePortMappings(ServicePointer pService);$ r7 C( F) G f5 ?% J( Z; C
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems); f# g0 d! w: ~
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
?+ y1 i4 ?3 C- ~* S3 j- N, ^ LPCTSTR pszInArgString, CString& strResult);% z9 @6 n1 P/ g6 n6 ]' r! }( \, J
void StopUPnPService();
) W8 N8 Y/ t2 `+ i& J
! z V" u' }2 W* M) k3 k: v
: @% \7 D; }) B" r* X R) C // Utility functions" f& ~* ?' B( M: y8 L
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);7 V5 z5 D) |- B0 S8 L- F* ?, Y
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);* c3 g: w- F, U8 c
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
* b5 i) Q1 _+ D void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);. i$ @! ]2 Y8 |2 K
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
7 O. w6 y5 o& X% `- E" }3 _3 E2 p HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);) f% p o3 U8 B+ C% K
CString GetLocalRoutableIP(ServicePointer pService);
# V) F' \2 `4 N! b1 e5 a
4 q& q8 K+ m% g) F. _3 J) o
0 L& [" U! ]' `. O7 a5 n// Private members6 @5 d: i' p% [0 [. \& @4 B, h' _2 c
private:) z( c: _8 \# T: N: p
DWORD m_tLastEvent; // When the last event was received?
) `; W" b. {) C& K std::vector< DevicePointer > m_pDevices;5 x: Q' \) W0 ^$ f1 r5 [1 j8 U
std::vector< ServicePointer > m_pServices; A2 G- B" @5 C8 i* w% K5 c* j
FinderPointer m_pDeviceFinder;
: s+ s* |5 D3 K& C* x6 \( j. d1 Q DeviceFinderCallback m_pDeviceFinderCallback;
; O$ V" D0 y$ v: ?: L4 S( h ServiceCallback m_pServiceCallback;2 a' q: [9 A. P+ T
6 G5 Y5 r4 b1 g! V+ |- p
2 O1 c9 ?' x* v LONG m_nAsyncFindHandle;
4 E4 ?9 i& z1 D bool m_bCOM;
- c& ]# q( X; ?$ Q4 \+ Q bool m_bPortIsFree;9 R6 ^* A9 d* Q6 d6 [
CString m_sLocalIP;
D u; [: y# |( M' A CString m_sExternalIP;
- E4 _. a6 Y7 k9 @ bool m_bADSL; // Is the device ADSL?3 g$ ^' {7 C/ M
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
e+ U9 \. v5 x0 ^% Y1 }6 _* Z bool m_bInited;4 ] ]- I- `8 G; o
bool m_bAsyncFindRunning;6 h+ e7 y4 U" s' |8 b( B
HMODULE m_hADVAPI32_DLL;- L1 X6 Z6 W. \. E6 U& D0 B, C
HMODULE m_hIPHLPAPI_DLL;0 Q+ [' X# L# p+ V$ K
bool m_bSecondTry;
8 H2 {) Z5 q C. J bool m_bServiceStartedByEmule;: F, N8 G5 d4 E% q2 K
bool m_bDisableWANIPSetup;
& c9 ?' k* }2 f+ U2 ~( ?0 V3 { bool m_bDisableWANPPPSetup;/ E9 P5 [7 `3 E8 Q* W/ N& x+ j
4 o1 N# i- M; l* i- ]" F
- r* B9 A2 y/ x8 s8 p7 X* i' C
};9 M, H1 i$ |( I5 s% Q# y. P
+ q" W1 u* i/ T! N* |0 I/ D- d9 Q% X4 n
// DeviceFinder Callback4 c, | H+ Q7 }
class CDeviceFinderCallback2 A( T4 {; q+ [; |, j8 [
: public IUPnPDeviceFinderCallback- M7 O3 M, l: M2 Z8 J3 C. z
{
; p$ _- T! T$ g( @/ ]public:4 M+ a, O1 w5 q8 z$ t0 o
CDeviceFinderCallback(CUPnPImplWinServ& instance)! R0 E! m( e; @0 l+ Y
: m_instance( instance )
5 C8 n1 \3 x4 u$ g- j- A6 z { m_lRefCount = 0; }7 E+ L# y! N* w5 g8 F" h# n
' B6 r5 E+ p+ ^ Y
3 ^$ d5 ~; X& ^! K5 m STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);# E! Q7 V# b) g0 e2 ~! S
STDMETHODIMP_(ULONG) AddRef();
0 E. V* n/ B" `: K9 r9 x% Z STDMETHODIMP_(ULONG) Release();: B# x8 ~. G; K7 l' @; ]7 x
3 x0 \/ t' N t6 k+ S% Z9 Y+ o4 `0 x6 ?2 A( ]+ z' w
// implementation
- N7 Y; E: z: A4 v/ H. {, s& k% uprivate:
! o- T( }6 u9 j! T HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
1 L9 k# l' l: P4 H \. ?( Q { HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);# H0 `5 M9 Q/ I% u& x8 e
HRESULT __stdcall SearchComplete(LONG nFindData);
5 ?3 P: P# z, W9 f) U
6 _2 K& G' O6 l. f/ f& X; R3 k5 o
private:' v! t5 V7 i" y# ^2 Y
CUPnPImplWinServ& m_instance;
) [0 E: l4 ?! }+ }* s LONG m_lRefCount;
2 b; k" L& O" e7 e: I7 ^& m};" {4 b+ [8 x p7 u( u
, z( ?, I* A7 e- g# J$ h0 ]. l" l3 ^- p. c f8 Y1 v% P
// Service Callback ' @( R' M% P) v% r
class CServiceCallback$ a- s) {3 Y& a9 g( @/ t
: public IUPnPServiceCallback) h! B, p" R0 u# X
{ D" P" O7 c0 m' I
public:6 x" ^; ^, d& j& [/ h
CServiceCallback(CUPnPImplWinServ& instance)
6 a/ D7 M' e! E$ d$ U y : m_instance( instance )
4 D! o9 E" B* d% }2 B { m_lRefCount = 0; } X1 b5 P6 b1 Y
0 [- l/ m; k/ P4 s
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
0 W( T! `. u6 f1 ? STDMETHODIMP_(ULONG) AddRef();1 h. _6 N8 u) o2 g) ]0 u
STDMETHODIMP_(ULONG) Release();
0 _+ T2 R3 _6 P m9 E3 I
3 F( ]/ r# [! E* G* G p
! y" H7 d7 Z/ g// implementation
7 w" [4 }5 `+ d! Z uprivate:! v0 d& b2 b3 H, } F1 }
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
- n, V; V& A9 Q) X* i, Q9 T! a HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);+ d- @) F$ b! ^8 Q
; \0 q1 z0 L5 T& i' ?% T" [1 S! K; q0 b- r# U
private:% C: b; O7 L" Z- N
CUPnPImplWinServ& m_instance;
! u }) F9 X! p! z6 e: t& E! q LONG m_lRefCount;0 r9 {" q9 s; Z+ E0 r* K. ^
}; P( Y& ~- r4 t$ Y
( k5 ^$ H/ k, ~0 T+ A- r6 f: F$ n/ f. D o% N0 u/ y8 L+ p
/////////////////////////////////////////////////) M0 C% j" ~* x. E( Q, `
3 b! z6 T. h( r
! M: i4 y* g3 Y1 V使用时只需要使用抽象类的接口。0 S5 s: V- a0 h7 x, R/ x* K) A
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
3 y# }! c3 q8 H' W! Y2 v8 FCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.# \9 O! Z9 }7 c8 z l, G
CUPnPImpl::StopAsyncFind停止设备查找.0 T! K- N0 y0 N
CUPnPImpl::DeletePorts删除端口映射. |
|