|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
$ T6 {, j, D9 P( q1 z/ O$ x. K* E! E7 _" c
8 l4 e7 T4 p, N4 V1 \///////////////////////////////////////////
6 W7 [9 n# b, o" M; }8 W9 d+ F+ N//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能." n) h& p7 _; @# h
7 k! u" B8 f b6 D$ Q; Y$ Q
( C* T. a" I, O; P% E1 a8 v1 Z+ V( c#pragma once8 O+ m7 m5 e' F7 I* U! N; R
#include <exception>1 q4 V- U+ l. a' U0 c; j
. e1 j( Q" b( W" Z3 u! F/ ^$ H$ V+ c/ S3 s1 J
enum TRISTATE{+ K: m1 [, {( D; ~- o! Q: _. V
TRIS_FALSE,
) m$ Z$ M8 ]$ C% Q) S& | TRIS_UNKNOWN,/ G( W2 e, L, i( B
TRIS_TRUE
3 g. S! s& b+ r- U% ^& p& ~4 w};6 @# P! V% i. F
4 k. ~" I% |! v/ o# ]! x( k, v6 Z, ~( b% O. A( W' |
enum UPNP_IMPLEMENTATION{: S% Z, K7 k3 N' o: w5 S
UPNP_IMPL_WINDOWSERVICE = 0,9 J" x) l( C, D/ _4 m: p7 ?
UPNP_IMPL_MINIUPNPLIB,
* n: z- k' h8 A+ c UPNP_IMPL_NONE /*last*/
% a' t; p- s2 ~};
) b8 K# E- J# l; I4 Z: p* T# K8 u. T9 u% c5 }
9 j0 I K' b) d& z4 H! o+ w5 p: i( R
5 R! x. M$ h1 Q
class CUPnPImpl: x& A% ~1 A0 t$ O7 ~6 R. t: ~
{! K8 i2 u: _0 }$ ?" B* n) o% Z4 I% u
public:
9 Q% V" W+ p( `8 F# X0 n CUPnPImpl();
. T6 F1 L$ a @. y virtual ~CUPnPImpl();
9 f1 Y) C5 E$ | struct UPnPError : std::exception {};
6 ]: V# h! T/ M$ `, U enum {
4 a. Z7 J2 ~/ ` e( O( K, N* Y UPNP_OK,
! e. h* I9 _, Y h- E UPNP_FAILED,, o! R: Y8 d3 |
UPNP_TIMEOUT- @7 i" K2 L" @+ D& x
};
$ H$ F0 D' a, s2 v" j
4 J1 E8 B# Y/ T$ {7 U" E
/ a' K6 H$ w+ T8 b+ D# w+ {9 ] virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;, g( @, z H5 Y: C5 n! z" u, W: g8 O
virtual bool CheckAndRefresh() = 0;
]3 }; Z$ c% W7 @9 n9 M, K virtual void StopAsyncFind() = 0;
- Z& s# Q& r; c0 J( T1 Q- ? virtual void DeletePorts() = 0;
( S. y/ H- f3 Y2 F, O1 I, q$ o7 s virtual bool IsReady() = 0;/ M! y2 h% b% r! A
virtual int GetImplementationID() = 0;" O! x9 i: }) d: c4 s
* ~! L1 y' a, Y7 n# z
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
% [+ d: k3 }. u' Z& A" k' M
- i. m7 q1 t' E+ T0 _; _! |; Y9 t! ~9 }6 R& X! P
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
! B% Q! ^4 U& M8 |+ h' t TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
) u5 p# D7 B/ _' i7 ]' y uint16 GetUsedTCPPort() { return m_nTCPPort; }
: J% p# u3 M) f& G& Z% I/ T! D uint16 GetUsedUDPPort() { return m_nUDPPort; }
2 d+ o0 ~7 M1 h$ [. `0 {* u' {
* d, i: h0 C) S4 G8 r9 Q% H- g, z5 Q
// Implementation
; Y/ Q7 P* S0 C4 m* ]; |0 {protected:
2 m/ X* N- V1 V1 O# f volatile TRISTATE m_bUPnPPortsForwarded;
) k; u6 a8 A6 l, z4 G void SendResultMessage();
% Q$ @" `4 V/ R, ]0 \( s" B; `" j uint16 m_nUDPPort;0 ~5 e% f% ]3 o; w9 E# `0 d1 U% V
uint16 m_nTCPPort;
1 U5 q, a$ b# }- _. ^ uint16 m_nTCPWebPort;
' q: z9 K2 e7 u$ u* B bool m_bCheckAndRefresh;
0 Q& m% I1 ^0 [. ]# o4 e( C3 |9 F) k" X* p
6 D4 d1 X7 v! r0 v# e- q" S
private:! k5 D& @- r8 c; C( \- H) j
HWND m_hResultMessageWindow;1 Q2 ?3 u* u5 |& w
UINT m_nResultMessageID;
9 d7 p0 E8 k, E0 Q! B% o P1 L
) G/ T* y6 n5 F/ ~
' {. t8 m; B, Y2 h, M) @; L};
R6 q) C, P$ I5 b5 @( t( [
: t7 g1 @. s) k, W. A$ N- t. n) P+ O" n8 y" H% \
// Dummy Implementation to be used when no other implementation is available0 m0 I+ Y/ {! a, ~
class CUPnPImplNone: public CUPnPImpl
7 g& ~5 P! b# Y2 W, P{1 i$ o. B8 ?' }" D- H
public:
6 Z( X, V3 J/ r$ h% R virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }, l6 |- N% \& d9 j" i2 W4 s
virtual bool CheckAndRefresh() { return false; }
! s7 s. Z- C& _/ X J virtual void StopAsyncFind() { }# C8 E8 Q( K: [' M# w
virtual void DeletePorts() { }
/ P- @- f0 J: E" i* {7 g+ p' ? virtual bool IsReady() { return false; }8 _4 I$ i; S7 M! l% C0 N
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }+ {$ e$ ~2 @" {% |
};0 L9 n. q+ ^" m
/ P) D1 s( ?' F5 Q- N. |" w
6 J; S+ i8 E; [; b- ^
/////////////////////////////////////
+ v, s- G% M4 S//下面是使用windows操作系统自带的UPNP功能的子类4 Z0 b4 s7 o7 P& r0 o3 C, z
7 l& q" W9 e) O2 b
- \& M$ J! a, Z7 u4 J8 m
#pragma once
3 N, D5 ^) k( p#pragma warning( disable: 4355 )
. C3 W2 s6 k, U' C; r
% G; _- B) K/ g# z% I/ _% s; C7 m. r/ b& P9 r/ Y& w
#include "UPnPImpl.h"% b. G# }. @, O( @& w: Q0 {
#include <upnp.h>
, i) G3 I6 _( z* Y' [6 Y#include <iphlpapi.h>3 m+ F- ^2 C% e+ V6 h5 @
#include <comdef.h>0 W/ H9 u1 t% L0 ~) Q
#include <winsvc.h>
. K0 c1 W; F+ \% W5 }& Z) Q6 F0 T1 A5 H
6 V: C4 O5 m, q% f$ Q#include <vector>
$ ]/ G: ~2 @9 k+ \3 z9 l9 V1 k#include <exception>/ A" `! J/ H" B& N1 J
#include <functional>
7 b/ T' d3 Q8 @9 P3 y2 O+ F& c: U3 Y, d6 g4 s
! ^4 M h2 J6 s
V; m$ d# s/ o. c
! ?+ ~) T; \3 l5 w! s3 w7 X
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;' A7 f8 S, g! @9 I. o
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
0 T' c0 ]: T! ?, itypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
t6 N6 }7 ?1 y" q+ mtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
! U! l& I+ Z. x% Wtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
; P; P4 G2 ]8 N) y1 ptypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;: Y5 H' G. B" J c
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
. ]; E2 K1 Y# s% n, ]. _/ B) T* e6 A9 @: T
) j+ ?' X4 W+ h$ W% Stypedef DWORD (WINAPI* TGetBestInterface) (# W! j* H0 W! ]4 o& a. n# e
IPAddr dwDestAddr,
( Z: p# O0 M7 { PDWORD pdwBestIfIndex) r& ~- \ `& f
);% j3 q5 x+ I$ v4 w
" ^3 b) ?) U. `2 B$ \
3 C. n1 W" Q. F+ `typedef DWORD (WINAPI* TGetIpAddrTable) (6 N$ G+ I8 s3 F% F. s9 ~# X% a+ U& w1 ^- v
PMIB_IPADDRTABLE pIpAddrTable,& |* Q* O7 R- j
PULONG pdwSize,
: u$ \& G! E4 p/ I( T+ z, I BOOL bOrder
" ]4 |# h" |0 Q% {8 N1 C);
4 [4 a" @8 B4 Y3 T2 I) B9 o7 x. ^
8 X% K: m- H+ b' htypedef DWORD (WINAPI* TGetIfEntry) (
( a5 ~' g( S- N0 w- \. P( f7 u PMIB_IFROW pIfRow
9 E; |- F$ M: { n4 W# c2 T+ @! C);
9 Z) w4 x( r. P) q" k7 J8 V( C' R9 V( N5 R. g, H- v& l Q
0 [0 O8 |2 x( n; \/ P
CString translateUPnPResult(HRESULT hr);* t$ ?8 [, g( f; \7 v: E3 @
HRESULT UPnPMessage(HRESULT hr);
# l6 D$ A- g" A- r
% H: W# v8 e( }& G8 y( t+ Y% R" T
! H* W" |8 f2 v/ g: D% \, dclass CUPnPImplWinServ: public CUPnPImpl5 E( E Z& j& t# p
{. n/ e& f! C1 z$ _ E% K
friend class CDeviceFinderCallback;4 F$ j7 {( J* t! A, [
friend class CServiceCallback;
: z! m- c& p) h" C7 ^' y6 N// Construction
9 C1 p6 D9 d' ^0 U2 d- tpublic:5 @* c: z) K& L2 ?
virtual ~CUPnPImplWinServ();! E! I* e1 _7 L N l; {
CUPnPImplWinServ();
# ^8 E6 Q- B7 a( W# [4 ^! ~9 b) ]7 @2 ]
3 J: K3 O( }. r' ~
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
& ]5 _4 N3 a5 t4 K- s( G5 q virtual void StopAsyncFind();
) u. n0 ]/ U! q( z y9 x virtual void DeletePorts();
7 j3 T+ T& P# E virtual bool IsReady();
: v# w8 m. p2 i% D9 U7 Y virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
. C0 w) F, `% p
& Q! X% }3 L9 Z1 o, \
, G$ }5 V6 ]8 `) V- e- P // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc). x& I9 d# K! J) b+ u" v
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later+ {6 @3 C, _. p C
virtual bool CheckAndRefresh() { return false; };
, C+ W! Z. y; C; ^" }! h; h! g4 [% O$ y6 k8 k" p& k m `! j5 X
% d8 c& Q( M) a0 v( H+ D* `! cprotected:
+ ]! q* Z3 g4 v6 k void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);/ P& `$ d! _, ]
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
4 T1 C4 {2 X. l# P2 r void RemoveDevice(CComBSTR bsUDN);( @/ y u% L! p5 F- q) l$ D
bool OnSearchComplete();
# m- {+ C" E4 K+ ?, i; J void Init();+ s3 O! o( }% E5 R- S
$ g+ v6 Y+ C8 O$ r+ G
1 {* M( i: Y( X inline bool IsAsyncFindRunning() + j6 |$ }/ U! g
{
3 F$ y a+ R. x$ n5 N3 [ if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
7 J. n4 j! c# |/ p' `$ z+ _: u* R3 | J {
! B4 E3 P6 J4 |6 [ m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );. |$ R6 x3 a$ R$ l% w/ t; ?
m_bAsyncFindRunning = false;
8 l' v0 A M+ O$ x1 P8 t: I. a }
y; t9 {+ @( K, m/ s" X1 \ MSG msg;) M3 t% G& [. s8 Y
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )! j3 |3 a$ n# f2 V$ B% @( V+ U
{! J ], x7 H0 ]) u# Y) K+ S: Q4 `6 v
TranslateMessage( &msg );. w4 ^$ c9 z r6 e: D* Z) V
DispatchMessage( &msg );/ C: i9 l* y) O _
}
; b3 v0 p8 i* `$ g# ^ return m_bAsyncFindRunning;
$ R# A5 r2 O" q' T- T2 J }
- h2 Z, ~) y$ _1 t9 U. h# Q
# ]' |, x2 V1 [ H8 j
/ l1 T* Q5 y o. i7 }: i% x6 L( d TRISTATE m_bUPnPDeviceConnected;
8 ^4 O) Z0 W1 X' F$ a5 O" A# k- a7 [- D- o, |( ^! s* J
2 v1 a0 B! g: B# Y/ E, w2 L
// Implementation7 |2 |- o5 K$ T( m/ I, Z: B+ p* K
// API functions
1 |3 J' I+ a8 K: K/ @0 T5 Z' G SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
, W- c! g7 I9 d8 W; P6 ~ SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);0 L3 G0 B% A" }
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);- P% O. p* w5 t) m0 _0 m
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
. j' b5 l; u ?3 y- W( U: z BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);6 M- F V: D+ b
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);& u7 h/ |% j3 w' b1 y9 j& Z, `; l
( g% B: m+ l7 j6 F9 e% _8 @: h( D9 q
TGetBestInterface m_pfGetBestInterface;7 y' y& u- X) y- A7 j ]
TGetIpAddrTable m_pfGetIpAddrTable;
- Y$ I2 g, ]! O( L TGetIfEntry m_pfGetIfEntry;
5 ?2 g" l5 h3 U: ^8 D1 K
1 z) ~" [4 b, U9 ^5 g& J7 W/ E; T/ }- U& O8 U# o( f; H: t
static FinderPointer CreateFinderInstance();
4 }0 i+ H4 S% i. N& A; o6 P6 E" n struct FindDevice : std::unary_function< DevicePointer, bool >
5 |& u0 u% m% f {
- C, B; w8 U3 D FindDevice(const CComBSTR& udn) : m_udn( udn ) {}+ L2 h. k. T6 ^# f1 S/ d
result_type operator()(argument_type device) const" g' {; |, o8 p2 w$ w
{
/ [, o: R/ h h3 C* H" I& T CComBSTR deviceName;3 M. e* S0 v( M
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
- X/ Z+ p1 Q( n- B+ k$ Z8 X7 f$ U" e: G
8 r: d$ h0 D2 u0 g& Q% a
if ( FAILED( hr ) )
) n/ X5 @; [$ r/ h2 G, j: n% @ return UPnPMessage( hr ), false;
/ F3 h+ [; R* h" h& l
! n% q4 d3 F; I/ ]; q' ^2 G
) w' H5 z& a, ]$ E2 N$ V return wcscmp( deviceName.m_str, m_udn ) == 0;' x/ [2 U( U. U" J, J; b1 X# B% \
}: v0 x6 i- Q3 ?1 y# h
CComBSTR m_udn;
?/ ?' R: a& E8 r9 m$ V };
9 h- g4 D5 ]1 `! B 8 d; X+ g- N+ `) w
void ProcessAsyncFind(CComBSTR bsSearchType);
* v$ I; X; o4 M/ f3 D- u HRESULT GetDeviceServices(DevicePointer pDevice);. D+ p9 U' b/ @
void StartPortMapping();
1 u, A& E& ~% i2 f- i1 L4 O. f HRESULT MapPort(const ServicePointer& service);
& i" F) H! ]1 r# u: _$ |) Z void DeleteExistingPortMappings(ServicePointer pService);. `7 f. Z6 k+ @4 s- S5 W
void CreatePortMappings(ServicePointer pService);+ Y( B8 U+ w1 ~
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);$ S9 [8 S' {; \7 Z2 K
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
& r5 V9 C/ G0 ~% X* f- N% A LPCTSTR pszInArgString, CString& strResult);+ |- w0 U! [2 A4 Y- t
void StopUPnPService();
# b6 r: c& g" v/ s4 S9 n# K3 Z* Z+ l4 ]0 k7 Z- q- ]( E O
6 W0 b9 X6 |0 P. u3 f2 j% t // Utility functions
) C9 v8 T/ E' B) V: K HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);1 z5 F' j) z: x3 N: r8 ?
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);. |+ Q5 B B4 R% e; I& e8 c' d
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
$ P% E7 M9 J' D* V void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
& c6 Z' j) o) }% `3 v, i0 A3 J. e HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
; Z3 J: }/ {+ g3 y HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);! E; S# P, w# M
CString GetLocalRoutableIP(ServicePointer pService);
8 @5 t7 e: _9 [! c2 P5 F3 T* x7 w, b. {: b1 S! I
3 |8 L" L) H, I7 `
// Private members" Q* C+ ], C0 ^- W+ ^
private:
; m7 w7 [( I) H6 d DWORD m_tLastEvent; // When the last event was received?+ c, \# n% {; z) y
std::vector< DevicePointer > m_pDevices;
: _( u! o7 r! w( O1 x: ? std::vector< ServicePointer > m_pServices;) m& F, ^& s! Q
FinderPointer m_pDeviceFinder;7 ~4 v! @- s) p3 y2 b/ K& I L
DeviceFinderCallback m_pDeviceFinderCallback;3 c0 b+ s2 x$ A# o# j; j3 w
ServiceCallback m_pServiceCallback;1 _) i4 c$ b p1 S8 r5 B+ v
% E! M2 C6 \6 K6 g% M: k* K$ Y( q) O) g% x" i. @
LONG m_nAsyncFindHandle;
$ |2 s1 [5 D6 M bool m_bCOM;! {' X R1 Z, l& k# y, x
bool m_bPortIsFree;
3 H) ]$ y `1 x# L. b CString m_sLocalIP;
' Q# z/ J( U$ \! n/ j CString m_sExternalIP;
/ T# _2 Y+ H# O bool m_bADSL; // Is the device ADSL?- S: s# X4 U/ @' Y4 G6 N' l
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?! E5 D: m |" v- v) g( M2 n
bool m_bInited;
$ w) ~4 ^5 {) n bool m_bAsyncFindRunning;
$ g: ?0 s' h/ Q1 I HMODULE m_hADVAPI32_DLL;" f; T' V$ K( j4 F% X
HMODULE m_hIPHLPAPI_DLL;6 H5 B6 ^/ Y' v# t/ I
bool m_bSecondTry;
+ H, q0 k5 h$ V$ E4 ? bool m_bServiceStartedByEmule;6 }8 j+ } @9 d* L7 x# a" g9 s0 H0 p
bool m_bDisableWANIPSetup;7 I5 A8 |; a# l5 }( O* T& z# O
bool m_bDisableWANPPPSetup;$ N; h( K5 b. K3 ~" R9 A
& ^$ w; p |$ j, p
: w+ K" x& y) C) l" d% }};8 Y" q: g/ d* @2 Y8 b; x% |9 @( w
6 t% ^5 x9 L* R0 | _
$ x$ k4 @7 ?( V! e5 U8 g: s// DeviceFinder Callback
1 v( T0 N+ _* @# ?: v9 D$ Gclass CDeviceFinderCallback
3 T0 P' [+ C& c4 C, v : public IUPnPDeviceFinderCallback
$ F) G- V4 ~# ]/ R{! g# M6 y- E$ |- g$ w
public:6 `. J; C( `$ B8 V& U% S8 S" d' d
CDeviceFinderCallback(CUPnPImplWinServ& instance)
% p* ], y+ |( j. Q1 G : m_instance( instance ), W0 N2 u' C: S; v) q
{ m_lRefCount = 0; }. c5 O7 s) E' g0 N+ Z k0 G
3 ?) K( q4 g2 i
% l0 j, X& X7 d/ u% r, d2 m- B3 C1 m STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);$ O7 L2 a1 e7 s A* R7 ?
STDMETHODIMP_(ULONG) AddRef();
s* h, w" ~( Q2 V2 m' g STDMETHODIMP_(ULONG) Release();
5 m" I5 x& e1 @& n# m3 d6 ^
; _& P: o2 O/ z$ [5 P- V
% G- K( C: `* H// implementation2 Z2 [: a6 {! S; ^- x' c0 l
private:( h5 e: K2 b) \6 r% i- n
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
) W- \( y& P6 @$ _9 D5 D- w! I* ] HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);3 t7 j# M' P3 Z' o2 v m
HRESULT __stdcall SearchComplete(LONG nFindData);
8 l# J# o& q# [, J( q
8 K& g2 A; i" c" q. g3 |3 u/ W
/ n. r' T1 a, g+ q7 r/ lprivate:
g$ R& j" w" H; l CUPnPImplWinServ& m_instance;
0 O* U) A" S0 ]6 T: K LONG m_lRefCount;4 p2 r; T! |1 [- q! I1 L
};& j1 u& Q% s J, W
( |% W- Y- j* E& P6 R; L: J3 c( r3 R4 M ]) e' r$ s7 P
// Service Callback
' Y4 I8 A& w `3 Iclass CServiceCallback
" b$ ^) z8 o& W# _ : public IUPnPServiceCallback/ }" V4 i9 [0 z, U! p
{
$ T7 |3 E3 b1 d1 ?3 ]public:9 |, G0 K3 C8 z% _2 p
CServiceCallback(CUPnPImplWinServ& instance)$ @. }% \2 x1 c. v5 o
: m_instance( instance )$ G" G; _6 A. [& j2 L
{ m_lRefCount = 0; }
! Y3 \3 Q1 X# n6 _
0 M6 J @; q3 X! p STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
0 S' V; O4 Q2 T" o3 s STDMETHODIMP_(ULONG) AddRef();
( J* d* b/ l9 B7 z" W STDMETHODIMP_(ULONG) Release();/ g: p/ t) L( q6 E# u1 d
2 p2 u9 W+ [% ?8 w8 Z. @ X. c& x5 X, c$ h
// implementation" A4 F5 m8 u3 T& a
private:: J; O( N3 d# J+ Y- O& a
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
5 f, o) m s" f# [$ q* w HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
, F4 r/ ]6 U) V+ z$ a# j; }& [( ~6 R& N
0 }& |1 p5 R3 N% W u9 Q8 K U
private:
% T( X# }8 t# Z0 M* q0 A CUPnPImplWinServ& m_instance; S$ z* d$ h' ? q) Q
LONG m_lRefCount;
, O. B( @1 Y8 e R# o J% w};
; p/ m/ }' ]( F+ x7 P6 | O2 g& ?6 K
/ [2 r+ Y" y- I9 X4 y! j3 W0 N1 G" M0 F/ D6 f, L
/////////////////////////////////////////////////
?, Z/ W/ g0 m8 j
3 X7 m, {2 Z" o
2 [! P W: v4 v! y- ]使用时只需要使用抽象类的接口。
+ I1 i T1 P$ s/ XCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
7 M2 z4 F# S! a( U4 C1 y, D J4 uCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.1 g2 D7 l7 Q* _3 [ U+ `( a0 F
CUPnPImpl::StopAsyncFind停止设备查找.
* ?$ s' [" N* u: m" Q5 R$ ]9 z0 D TCUPnPImpl::DeletePorts删除端口映射. |
|