|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,0 b4 `# n. h8 N9 S
2 |- M5 D: \6 U6 E8 j7 S/ Y p) b6 A. e' ~8 J/ e3 Q" v; W
///////////////////////////////////////////
* c9 t1 {2 v) H- T3 p8 {! ?//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
) z: ^$ P# Z* `( I6 B' s
# U5 [' p2 i% c9 J+ i
' ?' p! _( f" `5 W$ k7 N3 C#pragma once
. [" A8 B Y9 O( D& q#include <exception>
% I2 J7 b# ~+ l) {6 p8 c1 _! G
" d4 ?1 |4 K' _7 d, V/ o0 `6 \, b. t# l6 H
enum TRISTATE{! ?3 n7 W5 F: i* g3 S% a/ R* }
TRIS_FALSE,
" A" ~* _0 O" a/ d$ T7 Z) I( i5 @6 z TRIS_UNKNOWN,. m. H2 g' Z$ z! X7 v0 S4 K4 v
TRIS_TRUE8 d, {- q) \" R. M/ I
};
) K0 J$ C- Q+ b/ o& d" J6 `9 ^/ a+ K
# O$ Z+ c" V g0 C7 ]5 A* S0 Z, e- k, L9 p( X) V
enum UPNP_IMPLEMENTATION{ Y6 R+ s' m) Q2 {, A
UPNP_IMPL_WINDOWSERVICE = 0,) k: J; F( y/ C8 h8 J5 R
UPNP_IMPL_MINIUPNPLIB,
- P$ |' v5 m( H# H# S4 b; U UPNP_IMPL_NONE /*last*/3 ]; L7 H( g0 A0 d" G/ k* Z
};- H8 ^' C. B2 b
# k2 b' W' u7 b2 r l8 Z) h
* n' y9 X! B) a0 h% k, J# E* \# ^8 i% P
$ W( t6 k8 I7 _ o' a) y
class CUPnPImpl
0 I6 Y3 P z! l" C5 j' ]( h{
6 h( l4 S. C0 _8 i% g" a4 kpublic:% k c3 P0 k; _3 G1 z# _/ T
CUPnPImpl();
- `( t2 W: B7 {$ L a/ i virtual ~CUPnPImpl();
% P7 l" Z% h! k) y struct UPnPError : std::exception {};
, ?, ~4 V ? i5 @$ _ enum {% n+ ?, T& H s+ b2 ~
UPNP_OK,
' M# @" \3 L2 O9 J! V UPNP_FAILED,
5 ?. Y. U: |0 e; O0 ~5 q7 M/ ^ UPNP_TIMEOUT
4 Y: H. m' c% t6 e };; c1 r& `' e, @; S
1 e+ O. s) B" u6 K
" U; ?1 y2 g4 J/ v& a. s% N virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;3 ]! f% a9 [$ G" P: z. U
virtual bool CheckAndRefresh() = 0;5 t% g, n2 x+ g6 r. x- F
virtual void StopAsyncFind() = 0;
- j: h |1 }5 O virtual void DeletePorts() = 0;
4 l* B. h g! ]- U& a& K; {$ U, p% e virtual bool IsReady() = 0;; O2 q+ L9 v+ g! i* Z
virtual int GetImplementationID() = 0; B Y1 Z# B6 T4 q5 k
, L& I- u! U3 G& ]4 j( H void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping3 @4 t9 t* \9 L6 I, k- \
8 }$ ]2 B7 |' B, G8 q5 \4 a. v* F5 J+ `; j5 p# u4 d
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
9 c! e& n6 r; b3 x5 L0 Q' g TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }. |# N" R% T" }( t1 C
uint16 GetUsedTCPPort() { return m_nTCPPort; }( E/ T% C! I0 d- O$ x8 D2 u8 a) Z
uint16 GetUsedUDPPort() { return m_nUDPPort; }
6 ^7 X8 r5 Q3 O5 y9 ^' K
3 ^8 p- u$ k7 P! f
# l. _4 l5 c7 h) A" s// Implementation/ z* ^9 D- s C1 }7 w& D
protected:
( I/ J1 w; K9 [, U' B volatile TRISTATE m_bUPnPPortsForwarded;
7 F7 \* t9 v+ y: k void SendResultMessage();" [ j* |! ^: G' l7 Q0 u% i
uint16 m_nUDPPort;3 L1 p ?* Y# j& m, U2 O
uint16 m_nTCPPort;+ ~- T1 o( j) u
uint16 m_nTCPWebPort;& Y% A/ O3 ?9 o# K* g3 _# z$ G
bool m_bCheckAndRefresh;# O. D5 {5 [, l. M- R+ `7 U- Z
6 {' z, o9 R+ Z# o# c+ ?
8 v: N# t. }0 t& b$ r% {, Gprivate:% y; W, I/ O" X' J0 g& {
HWND m_hResultMessageWindow;( T1 f) z* D+ V0 p0 N
UINT m_nResultMessageID;
6 G/ I( G4 p/ u1 H4 t3 E& A# w6 x; s# L9 S( e& E3 V# M
# d+ W/ [1 m4 {7 D- D
};% q$ B; m6 Y$ e1 E, k
) B' f* \( ~0 ^6 u2 ?% j
3 V- a [ R% q4 r' W// Dummy Implementation to be used when no other implementation is available' Y! G0 u* _% U9 y# B! [8 Z) Y
class CUPnPImplNone: public CUPnPImpl
/ A7 A7 C1 l9 p& v: s5 n$ a{& Q- P6 v' s1 ?0 r# l
public:! q! }& s' N* m# C
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
1 v8 z: ]8 O7 y7 M virtual bool CheckAndRefresh() { return false; }+ T$ Q1 I- u/ {# B4 K. O2 K
virtual void StopAsyncFind() { }
2 V. H1 p2 x0 S; L4 V virtual void DeletePorts() { }8 L! ]0 U* C7 j# O& e9 [$ m4 d- q
virtual bool IsReady() { return false; }
9 b, C% [1 K: e1 r" t virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
' \+ R! l: r) d4 Q$ e) N};
9 M/ k- _( {, a% p; s% p
$ C- n) f1 V5 a( T% \9 |/ ?: z
/////////////////////////////////////
# s( _: G& H1 F! G. U& J//下面是使用windows操作系统自带的UPNP功能的子类
0 m" G: L+ J6 q, X8 W3 S9 l
7 A- Y& C5 g x0 ^+ D5 o1 S/ U" h/ S& W: `
#pragma once" z2 h( `% G6 k" o; Q" h' @
#pragma warning( disable: 4355 )1 g, d- S) C) U0 E! A9 \; Y8 w
9 R, K. d, x# q0 b. g7 Y$ x0 ?
& c' R' c; e R& `3 O/ F#include "UPnPImpl.h"2 ^& i/ c) f' h- M( x/ l
#include <upnp.h># h3 b- y- i! w
#include <iphlpapi.h>; N) O" Y5 _1 _/ m7 u
#include <comdef.h>
, ~6 k$ Y% `! f0 |+ H* d#include <winsvc.h>+ o( D5 i* n! i( l* Q8 `1 J1 Y! a/ Y
[+ o2 j, H) G. [' ]8 p# W/ L8 U" U0 ]
#include <vector>" H, L# | j1 i% a3 @* B1 X+ y
#include <exception>+ O, K: @7 H& p, U2 n- m' }9 f3 ~! c, {
#include <functional>
6 p3 J# }8 _1 O* v, b5 {. T8 g0 p' e# K2 Z
. l; t$ W1 h3 b& i1 ~) b" P( ` P
* V! J( `8 u% F
4 s1 u S0 j0 T5 R0 Itypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
& A z, _( R' N: l O5 [6 S) |typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
9 x( r a+ G, W: Ttypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
9 g) A0 {/ u, v( ~9 ]typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
$ x! m5 _+ B- utypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
! H. T/ Y; h* b4 Z1 l$ Htypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
5 `0 ~3 J8 }: t* j/ ~: ^* u- } rtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;) K& v8 ~- |- }. B# o; `
4 R' @* {: L( J n9 f3 C/ u: \9 b% q, ?# i, Q% F
typedef DWORD (WINAPI* TGetBestInterface) (, m5 D. b8 j5 w: v7 P* ?" Z1 ]4 k1 h
IPAddr dwDestAddr,$ j& @% {( X$ h
PDWORD pdwBestIfIndex
% _4 `4 I+ A7 w);
' _# L* {, W0 z; C- Y+ q, j
& S6 R2 j6 h3 ]( `3 y( H( a" C
% t( c D7 [0 H+ ltypedef DWORD (WINAPI* TGetIpAddrTable) (
2 U. e# ^, R) M1 L3 g PMIB_IPADDRTABLE pIpAddrTable,. ?: M$ @3 ^- G$ P' j: T- Q
PULONG pdwSize,7 Q8 Z7 i& x3 |
BOOL bOrder, L9 ?, Y" o! G
);+ z1 F( t, j b
4 q, @" k) b" t4 l( H0 s. _9 u
: d3 j" F* ~% \6 y7 v; Rtypedef DWORD (WINAPI* TGetIfEntry) (, e# f3 {0 Q/ Q7 z P" X- z
PMIB_IFROW pIfRow5 ]% J5 O5 `' F" |' U
);& C7 J! E( e; d( ~/ N1 p
; B# R8 U. ]: r1 S; C
4 r& r4 ]. b3 ]7 F5 b& n! r# ZCString translateUPnPResult(HRESULT hr);1 d1 y: n# y8 l4 o9 _" U
HRESULT UPnPMessage(HRESULT hr);( |* H7 x5 U% c: f' y
& J& r* B; Z/ p8 Z- A
2 {% S( ?* F( e6 f
class CUPnPImplWinServ: public CUPnPImpl) z; N7 U a' d" E3 r: k
{1 V' x0 h9 e! x( M6 N+ q3 y* R
friend class CDeviceFinderCallback;( V) \# r2 W; D
friend class CServiceCallback;# ?. t$ X( g. u! D9 `$ k, w% W
// Construction% O6 F) A( B* J( R/ S
public:7 K$ a' E% j' D" Z5 x
virtual ~CUPnPImplWinServ();
7 l7 S4 f ?$ e: ] Q1 V CUPnPImplWinServ();: ], g: z3 _9 G; ?) x
( Z. M. ]: ]! X* J9 V0 M' I8 l
3 S4 h0 @6 K4 {- n7 Q9 k1 J' Q' C: j virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }( R. Y! w4 k# \& o. k6 H1 A
virtual void StopAsyncFind();3 A7 k6 e: b, {( K( R
virtual void DeletePorts();/ V+ Y. Y& M. I) ~' A; \5 ^ p
virtual bool IsReady();! g2 E2 Z! L3 t
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }: \! b7 ?$ S# D6 T! r
/ D6 o& k" v, `/ e& ]
2 X" o% _! f0 s" f, } // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)* Q0 r- u6 L4 }, c3 k
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later: i1 g/ E7 ?1 v$ B8 Y8 H
virtual bool CheckAndRefresh() { return false; };
- x( C" Z" _; p3 b! N* o, r' @ V
* I5 g1 B7 ?4 E/ o& |* ]5 hprotected:- L' m/ Q( c; l% {+ U8 \6 l
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);! g! t( ^7 M* J, b
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);; o+ ~4 D2 @% E9 ^$ G- {) }
void RemoveDevice(CComBSTR bsUDN);2 w' n" [/ w1 v8 p
bool OnSearchComplete();
' E0 t/ U2 X% {' Q* Z void Init();4 d5 L4 _7 @+ d# j/ e
, R. e x& K; H' {& D0 }
3 _* _! z# s% f4 }: @9 J% X inline bool IsAsyncFindRunning() ) T- Z# A8 \! S* ]) p
{
8 I6 ~! A" N$ C1 W% e6 p& c9 L1 [( V if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
: L) [* W) i, c* q {
6 p* E, c K" X3 j4 s6 U' i m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle ); [& |- I: N$ L( H7 D! d
m_bAsyncFindRunning = false;
+ a2 a+ o. \2 y }) `' `- k" [$ w6 R* [4 W5 s
MSG msg;; ?6 H1 P& k3 b2 |
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )4 r a. n" m( i3 T$ C
{/ j9 V- |6 r c9 _: ^& W. i' U: [
TranslateMessage( &msg );" H4 m3 D: d4 b
DispatchMessage( &msg );
$ o/ `- n: Z3 f }
+ s: S0 Q- X. W return m_bAsyncFindRunning;& G4 G& m8 K7 K0 j' b9 }
}3 ^0 A2 t4 t* ~* t
9 E# f, r0 X2 b0 X" w
% M* _4 N$ i4 F3 j TRISTATE m_bUPnPDeviceConnected; n* e$ B% N- P: K( f3 D2 \' c) x
1 ~! L: N+ g& E3 c7 R- O
' @! P/ ~- \* ^$ C$ U2 [// Implementation* l, r' o3 ~5 C; m+ \% [
// API functions) e! E. @1 X& k
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
# Y* c5 b/ X8 v" m! N SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);( _9 H4 m# i; d) f L, R! F
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
$ e2 f' H5 ]+ h; _' z BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);4 Z9 i, E8 q! U4 v( f3 F
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
* y( t3 t$ d' q8 p9 y/ [ BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
$ F/ ]3 r# K: {8 X; q7 o5 j1 L$ b5 A% y+ s5 Q' Z
/ x, f, {* ? T/ L/ o) |9 R TGetBestInterface m_pfGetBestInterface;# J" N9 y, Y+ N: Y. q' O. d
TGetIpAddrTable m_pfGetIpAddrTable;6 z0 T; |9 Q6 F) [
TGetIfEntry m_pfGetIfEntry;
; J) J2 e5 W6 J; E8 H1 R" [, x+ H- c) r# v: l+ |
$ e. a+ i. A& s, Z/ L$ s
static FinderPointer CreateFinderInstance();
0 P$ y; I! @% d; h" p struct FindDevice : std::unary_function< DevicePointer, bool >& S" \9 x2 L3 j/ z% l) O# t& m: [( [5 t- }
{
) L) b5 [, d X) Q! M FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
% x ]! V7 U5 R; m0 z- ?) r. O result_type operator()(argument_type device) const
! m1 @# a1 T S6 |+ f+ ^5 |" i( F {9 m& W2 K4 a6 a7 B8 w5 _" I
CComBSTR deviceName;
0 U; B4 X- W c HRESULT hr = device->get_UniqueDeviceName( &deviceName );
& @. d# q0 w( r+ C1 M; A# h; E3 D" e c: K
0 O7 [3 j$ E1 g9 }" G" T* D if ( FAILED( hr ) )/ A+ R& C5 G, y" a
return UPnPMessage( hr ), false;
" V+ q7 `3 v+ O4 V$ v
+ s% R1 X1 X2 q( p5 w8 Q0 ~6 O) s
! y4 x" G7 {1 c6 O return wcscmp( deviceName.m_str, m_udn ) == 0;5 l c; J7 h# e+ E
}
4 h& |( a r4 B$ j( V6 k- ?' H3 | CComBSTR m_udn;0 N1 q! ?$ L: ~ u1 U5 o+ [# W
};3 O, Z8 z1 u9 s8 j8 D" U, x: l
9 o/ p# Q/ X" O/ A
void ProcessAsyncFind(CComBSTR bsSearchType);! H( x/ y* c9 J! y3 B5 ]
HRESULT GetDeviceServices(DevicePointer pDevice);2 A6 }8 v9 t# ~6 j; q
void StartPortMapping();
2 f! ^ A& Y% N1 Z6 G9 i! I1 S4 E HRESULT MapPort(const ServicePointer& service);
" e9 X8 @0 X$ s4 t8 k void DeleteExistingPortMappings(ServicePointer pService);
3 H5 l( {2 }* W7 a3 G: _ void CreatePortMappings(ServicePointer pService);6 w% \3 [4 Q9 W* D$ X' a% g1 a% v
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
8 z6 i( _; T$ z) ` HRESULT InvokeAction(ServicePointer pService, CComBSTR action, [+ c: A7 w3 T4 f* P" Z
LPCTSTR pszInArgString, CString& strResult);( C, H. t! k0 d+ Q" e2 q" W8 Q) {& {
void StopUPnPService();% l+ e8 h. d& n+ ?" v
O. B- ^' w- F$ C7 E6 |1 D7 h
$ e) D+ {7 S R0 t8 Z // Utility functions
$ t+ j. F3 W, n& y; v HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
K* c0 |5 U: i: f2 ]3 X INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
" ^0 ^8 E' R& m7 A9 v( o8 z INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);3 B: Y7 E8 p! O* C
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);- ~: _, N `: q9 L( u9 @
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);3 w7 N( J5 a4 R! o. {6 M. r
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);' o$ G/ o6 ~' W
CString GetLocalRoutableIP(ServicePointer pService);
; j. |; l2 o6 y0 p" {$ O9 Q& T+ _6 u; A) u+ m) P
8 c* i3 D, R# N2 W2 @* O// Private members1 \( d5 U. Z: C! F6 E# o& f
private:
1 B' n" @' m/ j( l: Y3 w DWORD m_tLastEvent; // When the last event was received?8 a* g5 B$ f$ x/ r; s
std::vector< DevicePointer > m_pDevices;
/ n' C8 W% i1 b- A" C* _ std::vector< ServicePointer > m_pServices;
1 ]% N- H7 `9 A" O+ `' G: b FinderPointer m_pDeviceFinder;9 d7 K, [# Z! F# n( W$ h) L
DeviceFinderCallback m_pDeviceFinderCallback;
6 ` x2 p) B' n* G0 ~+ c, k ServiceCallback m_pServiceCallback;5 X0 B" {7 @& w* T
( _ U7 e" D, B2 p
4 p7 p6 k) o" o
LONG m_nAsyncFindHandle;( o# q( b; ]. l, ? t( a2 H
bool m_bCOM;- P1 J# n) ?2 `5 `
bool m_bPortIsFree;
" p3 L* W( e" r: R CString m_sLocalIP;
A& b) \2 e$ m1 K7 U, d b O( ^ CString m_sExternalIP;
. g P% A- @, \' ]4 L bool m_bADSL; // Is the device ADSL?" U5 P& s7 e3 \# R7 b
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
8 t4 x C4 A5 D bool m_bInited;
# J* `3 U% U, b+ R( O( J3 M bool m_bAsyncFindRunning;7 l' p* g U" W! X+ j
HMODULE m_hADVAPI32_DLL;" E' C* Z6 |, F/ x7 D6 n; u- g
HMODULE m_hIPHLPAPI_DLL;, ~* q9 c, L0 Q- w* Z+ H
bool m_bSecondTry;
0 |1 r9 E: T5 X2 i" v: d bool m_bServiceStartedByEmule;, W+ p3 b$ |, r8 @
bool m_bDisableWANIPSetup;! Z O N' X, ], |. c( H
bool m_bDisableWANPPPSetup;
( A5 k0 t- A9 x5 c6 A2 o
8 K$ J- t+ c5 l6 {! _" R0 v
8 J. _# e6 D9 J: L2 ~$ t};
6 S* i$ a, w$ X% i9 y4 W
+ T5 j' n* X% l: S) ]2 [
* R7 d) J( B7 X& s; }6 T// DeviceFinder Callback
( h" [# `1 \5 r# fclass CDeviceFinderCallback
3 }8 \! _% m/ X5 H+ Q : public IUPnPDeviceFinderCallback% i- e$ H4 b2 v" \9 s
{
) w& X9 N, e; V; F' a/ B4 ?8 Epublic:
! @+ x9 d: x1 |1 g& ?% T" e CDeviceFinderCallback(CUPnPImplWinServ& instance)
. c( A( e* N# A! }2 E4 K9 d : m_instance( instance )0 [ E4 b0 p/ ^' c; d; u6 \ f; c
{ m_lRefCount = 0; }5 z, m; U: o' f* W6 x7 b6 P: s: R
' c5 o+ y; e9 t6 j- @: ^1 m l6 @: b% C% \7 c) X
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
; B0 F% k# Z1 w) ]2 h STDMETHODIMP_(ULONG) AddRef();6 s b: c2 l6 `2 ?. U/ X1 j
STDMETHODIMP_(ULONG) Release();, f5 H. |5 f. v; p5 F1 Q
; r# x, P0 d X* C. N' B/ h: V" n( s( [; ?/ G
// implementation
; a; M. v3 h/ L) `$ h$ Zprivate:
( H$ c7 U: j; \4 T/ b( g S3 ^ HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
- T2 l2 P: J4 w HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);, f$ y) Z5 z7 @. J2 L) `
HRESULT __stdcall SearchComplete(LONG nFindData);
- J3 ~3 h% a: q% T' a7 K0 T1 _/ z& k- M" ]6 f3 i
' h( a' ], ]0 m3 p) A8 m( J$ ~
private:
& r- J% P* {# B4 Z CUPnPImplWinServ& m_instance;
# W# e* n1 l, u LONG m_lRefCount;4 s/ ]4 K5 k' c( F3 A4 e, d4 F
};' g& K$ C; N3 W
4 L. ^: }5 x+ s) m3 o5 ~
; ]7 w+ n/ p" k( [( B8 Q// Service Callback % ?/ D( s7 ]2 a0 u; L2 }
class CServiceCallback, P( X2 q3 {% u7 \& t
: public IUPnPServiceCallback+ G" E. m$ d$ v
{
- |0 p# \( P7 R( q: Zpublic:
9 o* K! C% N" v% Z- Y/ N! e$ V# p& w CServiceCallback(CUPnPImplWinServ& instance)
- P8 D l2 z, r : m_instance( instance )
; \; e2 s; H, n+ l+ L: h* [ { m_lRefCount = 0; }
4 @1 F' M4 C! y7 X1 r
1 d6 @5 }1 Q6 I6 P0 V STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);3 @: O- D( L% l0 C2 z% W% G( m8 K
STDMETHODIMP_(ULONG) AddRef();
- y2 U% H w5 P8 s k5 R( n STDMETHODIMP_(ULONG) Release();2 K% _! @$ E* w% B4 Z! k! S% }3 w
* F: W7 ]: D: G: ~5 h1 \" q
) u6 N9 N9 t' h6 g) T0 s// implementation' E; q5 m, I6 ?' @# t7 R
private:4 D% T% k" u. L
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);- |( j2 p( K. }" K, }/ \) O9 ^
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
8 p$ C7 ]+ t" U3 V1 x! a/ |8 Y7 q: p) z% O' {4 l
( }4 T, J" }! l8 q0 }6 iprivate:
4 a, W k! {! I, L CUPnPImplWinServ& m_instance;
0 ^% _( b! J- X; V- r6 G LONG m_lRefCount;8 C6 v% t( B M3 u* }% m
};
8 r: I% l! l; H$ X+ m8 j. m7 i) y
& D( ^ T: V% l7 W$ u q; |* c$ ]
/////////////////////////////////////////////////
$ l) a% b8 t5 L' E' ?
2 N% a: ?3 R' B( e/ J5 k: J+ D/ S, ~ p7 @
使用时只需要使用抽象类的接口。% M* ?+ G6 c+ q7 m2 D' Y
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
4 @$ O8 M0 @; }( VCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
% G, i6 c; ?7 A' J$ m! i! h: VCUPnPImpl::StopAsyncFind停止设备查找.
4 M/ ]( U6 I! b) [& G# Q5 U9 n* e( mCUPnPImpl::DeletePorts删除端口映射. |
|