|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
2 d7 N. k* A$ |* I( c
D* S7 |3 I/ l0 c# R: a
5 F3 z, M* I. F* J, n+ i///////////////////////////////////////////
( {4 y o2 B% x3 j. K3 F" M//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
/ s+ u5 @ C8 Z8 a) S
( V6 i' M4 m0 E8 Z1 R
: p% C$ t* e6 ?. q0 [& s#pragma once
- C8 i$ C# n1 e#include <exception>; X8 i, y* ~. r! i, Z& @# [+ e% C2 I) F
/ `1 ?! e! q% Y, c7 t) ?: X- m
7 M) z( S- a5 U4 l: F* |8 M enum TRISTATE{; Y) R( ]+ a" B2 t2 y8 U
TRIS_FALSE,6 Y. v3 S/ |9 C5 ?: y
TRIS_UNKNOWN,' ~$ K5 ?1 V0 f! |
TRIS_TRUE
! }3 k5 K# H3 C. K/ I- N; S9 o% H+ O! _};; I- l" f/ c# @; |; v, h2 q
, p2 D5 T, w% J+ F+ a) Z C
; w) i! ]: Y- s1 W$ |+ |5 H
enum UPNP_IMPLEMENTATION{0 H0 Z( t8 A; U0 t; {
UPNP_IMPL_WINDOWSERVICE = 0,
6 T; v# b6 u+ s% h( ?6 b3 n7 K UPNP_IMPL_MINIUPNPLIB,: J* V% m% C( k/ [% t
UPNP_IMPL_NONE /*last*/
* N- D( A1 `7 ~+ i% @};- A( v; v- }# L# J! E( I/ R: y
( ]5 p) x" u8 `1 @& j
% }8 u H1 R- T: `! n* O& W5 A+ {0 a, t! e) J" k$ S
/ L- \$ X$ u9 f9 a" b) U& [8 gclass CUPnPImpl, ~; p! n, e& G( }! W) F6 l% W
{
. Y+ v8 @( q( B- C2 X2 Hpublic:
9 I% ~' \, |$ }5 z CUPnPImpl();, u: Z. j( g5 ?* A6 T
virtual ~CUPnPImpl();) h1 M3 X& E! R! m9 k$ q+ h7 S* B
struct UPnPError : std::exception {}; V" r; B0 L/ ~. x$ d9 v5 V. Q
enum {( n, u! E" |# v2 z' ~! [' V
UPNP_OK,
E, @, |# `) f: {1 M UPNP_FAILED,. k: R! B5 }' e# [
UPNP_TIMEOUT, P3 U) j- I7 q4 q2 D) t
};2 H% K. n" M! L' L5 i2 c
) H2 u0 [# M3 m" G( ~
' V2 p" r4 c) Q: z$ n
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
4 Y: f& q' @* V. Q" c9 @$ M virtual bool CheckAndRefresh() = 0;
1 L. W X* I5 v virtual void StopAsyncFind() = 0;
( K: R8 F c0 C5 i+ A4 w' Q virtual void DeletePorts() = 0;8 V' y1 x5 x4 [1 R4 X. W( D9 d& {
virtual bool IsReady() = 0;; `5 i: f; w: ^# T# ^9 I2 [
virtual int GetImplementationID() = 0;* O. @; [) r) D/ I- L
8 C& }5 v. ~) M Z4 x; }) q void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
8 B4 {# @# d1 i
' [ @2 Z$ H$ }4 V6 t% V8 D( u: t* a* c m( z
void SetMessageOnResult(HWND hWindow, UINT nMessageID);# y# A1 G" H; ~: p
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
7 Y' X4 F. D' B& v: L* b( D9 t2 h uint16 GetUsedTCPPort() { return m_nTCPPort; }
( R" ]6 S. s, a0 C( A4 u uint16 GetUsedUDPPort() { return m_nUDPPort; }
) {+ ?" o2 g- {6 h! u
2 ]6 R$ E0 ]$ S; {0 e# j' U, e* @4 q/ z3 H9 {" n! W) K
// Implementation
$ E, s% X# ~' M$ F& R1 u( H+ zprotected:. v3 Q2 }) u; R1 g; V7 s3 Y A0 g
volatile TRISTATE m_bUPnPPortsForwarded;
, }8 [0 @4 G b9 E! e7 R5 a$ M void SendResultMessage();$ v* u0 ~) ^9 Z: W9 ~; E
uint16 m_nUDPPort;- L) h4 K* O& {4 y! A( B
uint16 m_nTCPPort;
' F$ g/ q* {# G% Z; L6 {( i uint16 m_nTCPWebPort;% }$ B/ P3 x0 X d, @% e
bool m_bCheckAndRefresh;' o* J4 j1 K% r$ h) y# g
* l- x6 a% f; U$ ?( H& n
+ Q4 s7 v9 e4 t- \( r( x* k! qprivate:
8 [; S: K! O+ p HWND m_hResultMessageWindow;
7 [2 H+ b1 B, Q" D! F UINT m_nResultMessageID;3 z4 v, q* E# T$ @7 g
+ X: n/ U: j: x2 H" m9 a
) C8 p# R7 X5 W};
/ I; @: |; d3 [( _6 u; u; O6 W
$ ?. Y; ~ |! |+ q% H. @: y5 `; p7 b+ s% R, u+ T
// Dummy Implementation to be used when no other implementation is available5 e' U' q; v; }! Q
class CUPnPImplNone: public CUPnPImpl& q0 Y- J/ U% q8 L Q9 _! K* l2 F
{' L7 Z! R! Q+ N. Y _
public:$ C0 ]7 z) `) C! M, n* g, H
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }" W8 x) i. R; F( v
virtual bool CheckAndRefresh() { return false; }
: E( d- G1 z0 p# w$ \* J virtual void StopAsyncFind() { }; \6 K* B0 r1 ^' @ n3 _" H. G8 g
virtual void DeletePorts() { }! M# e) l2 o8 a# {! e2 {, ~
virtual bool IsReady() { return false; }9 V7 s X8 `' a, U7 l
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
# r4 k' g, y* M, C};1 Q2 b/ F- W1 v3 S7 T
9 ]5 T3 v0 t- r' D4 c$ s+ }
, l0 I4 N6 R ?0 T* s
/////////////////////////////////////* E; g/ [6 ^: ?- N: o) k. H! l
//下面是使用windows操作系统自带的UPNP功能的子类
0 @: k) @' M% A A, ~$ k# D% Z4 j' B2 x
, W/ H' q# R0 c& }$ J& T, O
#pragma once& r# m6 b% \0 U+ u5 y# P0 f
#pragma warning( disable: 4355 )
6 ^7 ^: u- S, K7 L) n5 H
1 {. X5 u. |- n" }. w" P2 ^: V; p
- P$ u2 K! }7 c#include "UPnPImpl.h"
/ H3 [4 a! Z. @+ a#include <upnp.h>
$ J$ [& ?! p# e2 u6 q6 Z#include <iphlpapi.h>
9 j: l% d' M0 Y/ @0 L#include <comdef.h>
3 _8 T5 l2 h D4 C7 s#include <winsvc.h>
+ S; j7 s" f: N( a
4 Y# d) q; Z7 W0 F# z3 y5 M8 z$ D2 S: a7 J, e0 a7 B8 r/ n
#include <vector>: l( L' q/ o% ^: }' ^' l' ?- r8 w
#include <exception>
h7 x8 d9 R2 ?, C; `6 I#include <functional>) |$ p3 ]! e9 T3 Q& H
& `6 @4 S+ E. q2 V$ x
3 I* n+ P$ t: Z0 ^* m
, c& g% A" t' c3 u
7 M Q( R: }' V! Etypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
4 t- H5 ^; {; t" B' {0 Ltypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
" d* _1 D7 E1 t, `$ e/ itypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;/ i0 Y4 P- q, N7 ]
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
0 s$ n1 R+ ]- {' ttypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
+ B- @" n. w5 wtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;& F+ j$ \. b+ [6 E# Q% Z
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;: T3 s1 W, g* R. Z% I U
- M1 Z9 i a7 }' F7 J
, s0 `4 E# r ?3 w1 }typedef DWORD (WINAPI* TGetBestInterface) (
: O7 r7 v( f6 I5 e0 ?- Z IPAddr dwDestAddr,* l9 \2 ^0 v% e2 @
PDWORD pdwBestIfIndex
# E6 Y6 H6 P2 M, r);% k+ w* Y+ ~3 l+ _
* v2 x5 Q* w9 p* y' Z h
$ d5 T' W( E5 r p ]" dtypedef DWORD (WINAPI* TGetIpAddrTable) (4 ]6 i* Q! U* }6 m. a
PMIB_IPADDRTABLE pIpAddrTable,6 `" C5 L4 Z% i, A9 H
PULONG pdwSize, {/ A4 X- ~5 n% W; m# U# R% v3 M3 I
BOOL bOrder
- I C. ~. k1 u- H3 [2 e);' T2 x5 D' L7 X/ D9 g
* [2 f) c# p* l+ D3 w6 e
- F& _9 g; _' G6 ?5 H. Gtypedef DWORD (WINAPI* TGetIfEntry) (, Z9 B: i% \1 E3 e: u
PMIB_IFROW pIfRow
* D1 z7 }' K, t8 \$ F* q);
( N* q$ I5 O6 g% u% b. r$ {' `0 h( s! _" n2 m$ M6 w2 y7 m
: i( `# a$ O& n. t* ^CString translateUPnPResult(HRESULT hr);
5 ^/ p1 s' @1 Q3 }/ z% K2 F- zHRESULT UPnPMessage(HRESULT hr);
0 ~) Z4 S. f6 S$ o; b- T; |0 S/ s8 X( `' F$ R% E! k1 u9 V2 s+ Y
( v# J# W- P2 n( R& c" m1 q8 n
class CUPnPImplWinServ: public CUPnPImpl: v$ H& Z* w$ m# N( Q, V
{
( `8 O: @- K5 X2 P4 J friend class CDeviceFinderCallback;
; u' l8 o d, B; x3 N- \: e friend class CServiceCallback;
5 u2 S3 R4 }% h! F5 _# {// Construction
' U+ k9 t7 X* a* e2 epublic:8 @- A) {3 ^9 l6 q5 f7 e
virtual ~CUPnPImplWinServ();1 l+ { G/ A/ l1 f4 _
CUPnPImplWinServ();
7 @0 ?' Z6 |; g4 b& _+ J8 Z- G4 q3 h% }+ A
" b& |/ S0 ]6 P3 k) Q% B virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
* [: a" n# w) ^: k. F virtual void StopAsyncFind();
* @% N0 ]# G+ h3 X! H. k" U2 f virtual void DeletePorts();+ w% f- [# k7 Z# Q6 V+ {! z2 M
virtual bool IsReady();
7 w: P8 I4 o5 D; N8 k, ]& T; y virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
- o) i) E/ g# v7 a, @! {( p7 I4 Z' }6 J) _/ ^# s( {
% q* F/ P- M+ h8 C+ x6 z // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
, w5 d. N; e- [8 {; @0 E8 S // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later. y# X V9 g' ^" p
virtual bool CheckAndRefresh() { return false; };. R. u% l5 s- [ N& W6 p }
3 a& T! j3 u9 N
, t8 V0 W( w: i7 D J
protected:
! @( T. m' y+ r) U0 ?6 K3 e2 ]; N void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
# D" y; y+ e4 E$ p void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
1 ` D! F0 N: O8 t2 m void RemoveDevice(CComBSTR bsUDN);" L5 P) W3 i& m' A, e: p0 Z9 t3 N
bool OnSearchComplete();
- [+ Q. [ Q! V# X- t void Init();2 G4 d- I3 k, s5 R/ J* V9 a
- T' O& ~- n' F6 h/ W
: u/ e! Q- K; S! X1 a7 N# h' r inline bool IsAsyncFindRunning() / ^; H- D$ _- u+ t4 I' D: o
{0 ]/ S& l6 u. H5 ?9 \
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ) v6 {- n1 ]! E: N5 d0 w) y7 B% U3 B
{
$ k; G$ _, z- s- I& f+ a" _- h m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );3 p! L( }* c6 j0 u8 }# k. }9 a
m_bAsyncFindRunning = false;
$ A8 q# P; R- K% U9 F }
: j, |8 {& s- |, R$ q2 L MSG msg;- W. H. L9 F; {6 E3 F4 v
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )- p% f( @8 @: f
{
- \; R3 r! {' U# Y TranslateMessage( &msg );
- u$ q, S! H& c2 u3 E9 N( |- g DispatchMessage( &msg );
& n5 d. A5 S. t: o4 K% K* f1 m* J }
( j: g/ C7 r3 I+ X; w return m_bAsyncFindRunning;
# P1 p( E s' b. P }
, R- G/ `5 q/ F1 i) z, u7 V
( L$ n' ] ~, g# H4 F. u
1 X# I1 {. K* H: [ TRISTATE m_bUPnPDeviceConnected;
! g4 E0 o# d1 ^5 E5 p4 a
8 U; }8 J3 B# h0 V. C0 U- }5 n) Z, i1 K
// Implementation# K/ S& m- P8 f) d# ~5 b6 j
// API functions( e( `& x$ ^' X) {' B
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);6 W: }7 @3 h- P0 |+ t- q. J
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
- ] d: h( p0 h BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
! H3 n C( e3 t, U5 \8 e" v BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);0 |9 h2 W' R7 u/ P Z9 H' T; Q
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
% Q5 c3 i F7 @7 s; M. x7 Q! ?+ ^ BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);" g% N! m0 F; h0 O% l e
! Y/ j" q( O' N( }
% c+ J0 g& R& I* ^. n$ c TGetBestInterface m_pfGetBestInterface;
- u/ Y! J ^# q( v9 l7 s* R: i TGetIpAddrTable m_pfGetIpAddrTable;3 h" Y4 K0 ~& e
TGetIfEntry m_pfGetIfEntry;
+ r4 H2 u$ ]5 B: D! X. _# ~8 U; V5 x8 o& Y6 `: M2 y
! G$ }4 [0 x/ o5 g9 U
static FinderPointer CreateFinderInstance();
5 z% C; r8 X# H+ n' ] struct FindDevice : std::unary_function< DevicePointer, bool >; L. L+ i6 r1 \3 {% F' l& d) R
{8 r8 d5 \+ o* C3 i
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}. h) F# r2 G! R! f4 B% q3 i8 G6 R3 T
result_type operator()(argument_type device) const
0 @" p7 [- g+ Y {
4 y) R# W* D; N* D CComBSTR deviceName;
7 }" u8 W1 r& q+ u/ ^ HRESULT hr = device->get_UniqueDeviceName( &deviceName );2 u0 Z0 G5 Z& H! a* U! k
+ A5 t! V% v$ u7 F! [. @. ^
& y: i+ P' K ?5 t+ c0 c if ( FAILED( hr ) )
! x( R# m6 S- K return UPnPMessage( hr ), false;
9 W& J5 k% a/ @$ r7 M" b- h/ D4 l" `* d% A
) O0 M2 k& d. O) V- k* p3 T7 l/ P
return wcscmp( deviceName.m_str, m_udn ) == 0;
# F- K& x0 Q! E5 ]+ q% V0 K: G }
4 D2 x: Y5 |3 Z3 u CComBSTR m_udn;
) {. G" j% W1 Z/ T! R };
! Z0 R f& m1 @9 `6 a0 _- T 2 d* u8 |! ]/ n; W) L9 w' q
void ProcessAsyncFind(CComBSTR bsSearchType);
6 K( I0 d5 b6 c4 L; P! T( J HRESULT GetDeviceServices(DevicePointer pDevice);
( L" u( h# l- z* Q void StartPortMapping();
: u. A S0 P# C1 _* @8 I' g HRESULT MapPort(const ServicePointer& service);
: B1 A" `$ b4 w* G4 y( Y void DeleteExistingPortMappings(ServicePointer pService);
: Y" v" L$ b1 B) Q void CreatePortMappings(ServicePointer pService);
\) j {; ]( c }* t HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
: n: {5 D( e Y$ U% O6 n4 t, [ HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
3 X0 r# r* z6 Q( L5 w, j/ Q LPCTSTR pszInArgString, CString& strResult);1 t& T% D+ B& x. j# [6 ^
void StopUPnPService();
: S$ J9 S( a1 b& T
* y" G$ D" l C0 T$ B! M* {* S- Y& \' z) x5 a d6 ~ w
// Utility functions
# r. m; V& ~6 N& w1 _8 n: D HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
, i _$ {5 b/ f ]& G0 i6 h' B* E, @ INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);7 o. ?) x: B) c$ Q: y3 K' u/ E
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);$ J- ], K% E& A1 H9 M& ]# `
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);" d! S+ k# \% d" O
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);% l% l' ?9 V% }+ C* |
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);$ z8 A* x4 z- e1 K, w
CString GetLocalRoutableIP(ServicePointer pService);( k4 n3 a' R* h3 m. R D' p2 P& O* g' K
) |" M) L; o6 R
4 d) ^2 I1 W f5 Y( t: R& ]/ e0 o// Private members
# |! A- D, ]3 y3 E) \private:
4 T1 Y) P& E; I2 H h DWORD m_tLastEvent; // When the last event was received?2 |% z! X, Y$ E: ~
std::vector< DevicePointer > m_pDevices;! U) v$ R2 A& g; `/ P
std::vector< ServicePointer > m_pServices;1 h$ h2 k/ M2 u: m; B
FinderPointer m_pDeviceFinder;6 _: ^! P0 _2 m4 j6 H9 i
DeviceFinderCallback m_pDeviceFinderCallback;
; {5 w4 J; K) F: x/ x' g; u$ M" Z ServiceCallback m_pServiceCallback;
% L6 Z7 H' M: c6 K: q" A+ H- H
+ @) d. S1 D8 z" h3 E: S1 H, z
9 s. t1 f v/ d4 C LONG m_nAsyncFindHandle;. _0 r7 N: O0 ] e
bool m_bCOM;
. _( S$ v g& V, U: e/ X! R, J: X! s bool m_bPortIsFree;' p% K4 O8 Q3 w! J2 g8 C+ z' s& D' ^
CString m_sLocalIP;1 A' j/ B# ]% _5 e; v% e3 Z% C
CString m_sExternalIP;
1 M9 i* X3 Z. X4 m bool m_bADSL; // Is the device ADSL?, v A# ]1 R1 s; B# Z1 e. n
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
6 @( n& P- n1 K bool m_bInited;
1 }+ y$ N; R. D bool m_bAsyncFindRunning;
$ S# V8 r, a' @6 s5 e HMODULE m_hADVAPI32_DLL;
B9 [9 r, S4 W6 s( p* ^7 V HMODULE m_hIPHLPAPI_DLL;$ `+ Y" `! B9 M0 p6 `5 [
bool m_bSecondTry;1 _: N! e8 p ^1 x
bool m_bServiceStartedByEmule;
2 r) L- q9 Q& u3 \* T bool m_bDisableWANIPSetup;1 `$ m+ L& S2 A5 L: R4 L1 w9 s
bool m_bDisableWANPPPSetup;' n7 L8 @: _% E: a
& z, ]! H W- {2 Z3 C) r( y9 @( X; B& `- v0 ?
};
" b( X X1 e( l+ L
! c. n3 e0 A& ]' e- ?5 j
8 X" [+ z. y3 a- O' E: Y// DeviceFinder Callback* k5 g q* T2 [ M: t2 ^
class CDeviceFinderCallback
$ z5 t D: e. ]% h7 X : public IUPnPDeviceFinderCallback
& x6 s# @! n- c. q: H0 p{& P0 b& R. n- R$ G8 V6 g
public:* m; S4 [+ g* ~6 Y) ^- r
CDeviceFinderCallback(CUPnPImplWinServ& instance)
4 {2 |7 H& ~& }3 a J+ V$ G8 \ : m_instance( instance )$ {2 a1 t9 D/ y! P% \7 a3 ^
{ m_lRefCount = 0; }
: |# u* m9 U7 k9 [4 r# I& E3 j6 F# a4 }3 k, p
, Q* h, G' w) M% ~ STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
$ w: D. N) b6 p' B( @$ F STDMETHODIMP_(ULONG) AddRef();; w9 f+ u* z! |( X9 O& y" {1 f
STDMETHODIMP_(ULONG) Release();
+ f; { \# R. T! _
- R9 [$ O/ E/ h% ^* a5 E
) k3 A" X, ^5 _* B4 F// implementation
9 a( r6 {: i( ^" O$ Qprivate:
. E+ h' ?/ F! n. c0 D HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);: v2 e) x1 o. r7 K4 ]5 N
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);- _3 V8 H+ R0 \ Z3 H
HRESULT __stdcall SearchComplete(LONG nFindData);
. K( `$ B+ d- f/ m# x# y0 F/ F8 p0 i5 x3 s' [4 T' Y
7 J$ P- S4 a+ l; @% r. P6 X
private:
. Y! {' m& B9 ?8 ^3 S, z, c/ d# O CUPnPImplWinServ& m_instance;' T- L- R2 U$ o
LONG m_lRefCount;
/ f8 N1 A' Y( }* Y9 a};
* a9 f1 l* i8 |7 B' H. E1 c3 |! Q- B
$ P4 p9 V! c: a9 z3 S6 Z
// Service Callback
, r; L& ^# v$ X! Mclass CServiceCallback
% K# v& \ c. S8 } : public IUPnPServiceCallback
' T2 v6 \% B$ F) F7 S{6 K; p; o6 r0 Q! H
public:5 [3 @' I% l& R7 L
CServiceCallback(CUPnPImplWinServ& instance)2 I9 f: h* L: ^2 n- H- b
: m_instance( instance )
% i+ W" o& t3 | { m_lRefCount = 0; }
- H& W# u% y, m3 Q
4 d, C u# U# @) P1 { STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
; u! U [# j- ~ a; P7 W STDMETHODIMP_(ULONG) AddRef();" U: r# p' q$ o& k$ H
STDMETHODIMP_(ULONG) Release();, j# [, ?4 X, I- Z! I
& K: [6 y4 X& O' `
/ l2 {$ _# u) w$ d// implementation/ `. x" n4 w* F# [! _" \
private:
; r$ Z/ P! U! ? l* ~! A& X HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);; C' B. [' @3 Z3 O
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
0 h' P& {7 F; [1 J7 a& W" I& Q4 Z& b; t
3 u- V( d/ P6 sprivate:
' u G8 N+ W( {6 {1 ~ CUPnPImplWinServ& m_instance;
0 q% k% V0 d6 q- W3 x# \ LONG m_lRefCount;
6 Y' f" x/ [$ T3 I; }! n& ]; l! J};" d% Z9 Z$ a+ G5 d, z
& K% C, ~% u. W; V0 k% |! Q, U
# w# S4 Q/ l. B1 x1 Z4 r/ d
/////////////////////////////////////////////////
* z5 L7 p" J; Q9 U" _4 e: Y) D H/ O$ g
8 o4 l$ ^& R, y' b4 B8 r2 v使用时只需要使用抽象类的接口。# L% r# A3 q, p- x) m1 S* a
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
' V$ M6 v: V& m/ t: nCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
9 i4 t3 E$ V& P! b" ~8 h1 hCUPnPImpl::StopAsyncFind停止设备查找.+ ` u5 u9 N( C+ a
CUPnPImpl::DeletePorts删除端口映射. |
|