|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,! m6 V7 T6 h7 Y7 j* Q/ c9 C
0 S5 L S' w. b+ A# d' L
1 x8 ]$ e. H4 j$ q- c///////////////////////////////////////////
0 ?# y% _, ^8 [//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.; P8 n& t3 ~! J F- y, _/ S
9 r. q4 V( l. z$ `6 a% Y
0 k* B9 g! L" _* x9 S#pragma once; }7 e/ o4 `$ U$ I! J
#include <exception>
. n* `: a( b( ~7 z) ~) n8 ]
7 l8 |. t0 ] j7 j$ s$ e
2 o( C: m! s! m" _7 H4 P/ P" g6 X enum TRISTATE{
) v" r- b) F7 n8 u$ y TRIS_FALSE,2 K/ K* ^4 C0 @+ b9 |) a+ L
TRIS_UNKNOWN,
+ G {$ o" g/ ^+ z6 l, t$ e TRIS_TRUE
8 B3 V$ a- b m5 G9 x" f* C9 U};
+ R4 u" j: Z& M7 ?8 L0 P5 _ p1 s% Y
; b6 l- @5 b" m* L6 Y8 J0 e8 genum UPNP_IMPLEMENTATION{
# J6 O+ _) U: }" k4 m+ C' g UPNP_IMPL_WINDOWSERVICE = 0,
" ~3 h! ~& f B; c" ]- {: Y UPNP_IMPL_MINIUPNPLIB,
* H$ J' R) w! U7 T# x; | UPNP_IMPL_NONE /*last*/, S3 f6 S5 N6 z. `
};
7 x7 H( f" N' Z! N" J, C) L- R7 W5 j% V, U$ A# z
1 l& o0 S3 }* I3 x+ @ _. l
! h2 W* p9 V* D: s7 S R* F1 d, X
class CUPnPImpl
" g% G2 |% j8 X7 l& I0 R4 h{7 Z+ f% @, H& n5 n) N; [
public:
% r* {1 h4 [# ] F, @7 C ^' E4 K CUPnPImpl();
0 J% P4 g3 w" `0 _9 F" Z; S5 H virtual ~CUPnPImpl();/ D6 m# N0 Z# l$ I1 R' `7 Y
struct UPnPError : std::exception {};( h3 E7 ? i& F0 S9 B+ [ r
enum {- E. C8 j) a+ m/ k
UPNP_OK,
" ?+ C6 G, a3 {. d0 F: _8 t UPNP_FAILED,8 L. L T: N5 p6 C& d% N3 h% n
UPNP_TIMEOUT1 S$ Z3 r" h0 a0 P; z
};
. v$ e# x/ j. E& m8 n: L1 z' v. N! o! b: v
|, x( X; _# j) i( `, g: X" g( J
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;, V- i/ K L6 q) ~5 g3 x$ ~0 ^
virtual bool CheckAndRefresh() = 0;5 ?0 \4 g' e& l& ?( d
virtual void StopAsyncFind() = 0;
. M1 S9 g- ]" j# s+ E# e virtual void DeletePorts() = 0;
+ F5 }6 g6 N! D+ I* V& W0 B8 P5 K virtual bool IsReady() = 0;
( m" r2 i! U8 n! s% q$ _" H virtual int GetImplementationID() = 0;/ e) A c7 d0 x
$ Q( ^1 i9 L+ y
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping+ e& E2 A) G9 I& x
7 Z% e8 m* H8 d$ P2 Y G3 b& u: A% Q- S2 o
void SetMessageOnResult(HWND hWindow, UINT nMessageID);& u; `0 r- O' y s5 g" C
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
1 ]/ `6 U0 ]# i( S! ~ uint16 GetUsedTCPPort() { return m_nTCPPort; }+ b& W* l& V7 D1 `+ x! l
uint16 GetUsedUDPPort() { return m_nUDPPort; } ! H1 t6 H# A: P* J: j, J
5 a3 u- V0 j4 M1 x% n; }$ l q! a4 [
2 U+ ~# {$ q5 |. K, H- d6 N6 V& O// Implementation% x4 l0 V: ~ ?" n
protected:8 m: }- P5 ^( N/ S! {/ L: E
volatile TRISTATE m_bUPnPPortsForwarded;8 C4 L# ]# O7 d7 R7 d
void SendResultMessage();3 y( I5 o( h+ C3 }; n) a |* |( O
uint16 m_nUDPPort;* y0 ^% v; c( n. i1 P3 H
uint16 m_nTCPPort;
8 a# A8 s4 |; {0 d4 X1 T, m# { uint16 m_nTCPWebPort;
: K+ H% U' v" T8 \2 P/ Z bool m_bCheckAndRefresh;
- {: H; o* q2 C; i+ H
. [( ]5 t c# e- Z i N. m2 \2 c7 C8 h5 Q7 V9 m/ W t5 B* Q
private:* I3 h3 e3 F% f9 z: }) Z/ a4 N
HWND m_hResultMessageWindow;
1 B, G/ r* L H, G UINT m_nResultMessageID;
) N3 M0 S* x6 m6 \4 X" S3 Q" Z' i. I) d
. y+ R/ i) {$ C0 b- d/ h0 L4 t
};
4 w. i8 J" T; S
# v, \7 g0 P7 B! ?8 I' {7 U; u6 `4 M" S% d
// Dummy Implementation to be used when no other implementation is available6 L1 `. w' A) Y8 j
class CUPnPImplNone: public CUPnPImpl
% o' K6 }6 D5 D- |{
0 ^$ ^# _3 x% Fpublic:
) q- u4 t8 ? K$ T" j8 G- V virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }8 v: q: t0 W9 U: N0 Z
virtual bool CheckAndRefresh() { return false; }" ^2 r% I* L# Q% l
virtual void StopAsyncFind() { }
# @2 u. M3 a) }7 W5 s2 Q virtual void DeletePorts() { }
5 G3 {; r k) ^; U- u; b virtual bool IsReady() { return false; }
2 x0 ]: Q, Q' q" V: K. r" i0 [ virtual int GetImplementationID() { return UPNP_IMPL_NONE; }. H2 `. d, }' y' Q, M! e; T, \
};
* R$ T& c, W- V' `$ o* I+ \9 \+ t+ N) E' v2 M
1 b# }/ |( l& @7 ` y/////////////////////////////////////2 `, X$ \. i6 q
//下面是使用windows操作系统自带的UPNP功能的子类
5 P6 c8 o; y! t; e: Y+ b' c
6 a p2 R7 B. E8 a# p' r. Y; Y( F* o4 Z$ g4 u
#pragma once/ q4 \/ D$ V6 S: s' d
#pragma warning( disable: 4355 )/ U+ L1 F8 [1 r0 u- S5 U* ^ y
! p) j9 J# Y5 k6 ~% P4 p; Z
8 T' n5 l. r9 p- r2 p% ^+ V#include "UPnPImpl.h"2 C* L$ j D& W3 S4 e. i
#include <upnp.h>7 c' H& N1 y: ]. K% K/ @
#include <iphlpapi.h>8 U: | t: r9 }; R, [
#include <comdef.h>
" g/ l9 w, [: h" {#include <winsvc.h>
7 V/ I) n" B, G) [ \% {
$ x; w* q0 M6 I8 P4 P6 d" ~
+ t* W& U! w1 k4 F! H) X: d- Y) i. m#include <vector>4 m: v4 T0 g9 x9 H3 v/ G1 K7 E
#include <exception>
% x9 a; G- T$ r; r$ E' J6 a( {#include <functional>6 J3 ]* K* K f
9 ]7 @" l* q# m
: V: @; _* b* X" y4 ~
/ P$ W( W' }2 a. D3 [7 p# j; G. N; }$ A: f! `
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
* u8 P0 T9 t* _, G" f0 n Gtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
) u# B9 X1 O8 Ttypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;, ]2 [# u) |. @) Q7 g- z
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;2 l+ v) k8 u% D) L
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;: Z$ i3 i/ t# Y( w7 Q
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
! Z3 q% f2 d8 g) d; Y; Htypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
* r8 _0 D: g5 l/ N; X, u9 k
' g2 M. Y. j: H) D# D K8 }1 Z; C
typedef DWORD (WINAPI* TGetBestInterface) ($ @! S; z8 p" t& [6 k
IPAddr dwDestAddr,
: M9 a1 _0 z3 P0 _ PDWORD pdwBestIfIndex
# h$ y! [7 a2 }: b);) ~9 ^) |* l D2 U. C
$ ?" E( C7 O& I+ a p
, x1 p" K- a5 r' a' ?typedef DWORD (WINAPI* TGetIpAddrTable) (
& _' T2 }. J- c2 L/ ]' A PMIB_IPADDRTABLE pIpAddrTable,
+ V5 _" @; G! c0 k6 o Q Z PULONG pdwSize,
! f, s+ O0 p& R( v9 a# R4 M BOOL bOrder
, Q9 V& H) v G);
5 a; e0 m) A, g: L, T8 B2 {, |0 ^
* w8 P. ?. R$ L- G2 |- p4 F2 A" C+ b$ @# F3 _+ u
typedef DWORD (WINAPI* TGetIfEntry) (! @9 N/ I. _4 z4 @/ [+ e
PMIB_IFROW pIfRow' q q3 h* ?' V" o" g6 i( P2 H
);
2 ^3 A/ t \7 ^7 T8 }9 a/ n' H) U! x5 c* x
2 E% p# q2 T1 w- zCString translateUPnPResult(HRESULT hr);7 @( {# d$ {' L% V
HRESULT UPnPMessage(HRESULT hr);
* } s' V" C7 C% y/ C7 O1 `1 v: w5 K) \" c
" S4 U; t! L0 }% {; @class CUPnPImplWinServ: public CUPnPImpl% [ z# I. b/ q4 T7 R, ^5 v
{
! t+ I7 a, E. C8 u friend class CDeviceFinderCallback;
5 o1 K! e0 [* {& X4 f; A- J* s friend class CServiceCallback;
4 A- p/ `! l! m// Construction
J4 G0 U; M! n3 M1 ~- _! n$ Fpublic:% Y' |3 n- d9 G5 ?' }
virtual ~CUPnPImplWinServ();2 r9 y5 R/ f+ `! S2 N9 x- ~2 ?
CUPnPImplWinServ();
3 d% x+ [0 g, ]1 N+ K
' C8 z4 ~* B- x, y) F1 y4 c
( K, _. ^; J" V3 T5 z" ] virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
+ _$ q5 @0 @( U- {) L( R Q6 _9 | virtual void StopAsyncFind();
4 a. o$ H$ k1 j. o4 t virtual void DeletePorts();
$ S4 g$ ?1 U+ W, |4 G6 I) S6 I5 n6 X virtual bool IsReady();
0 ^6 B9 \9 A- D# z7 Y virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }0 ^ k- E4 H& b8 \+ @
2 p! i" p" f4 e
7 ]0 A4 w5 A* H) x# C0 J" _ // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
/ u2 C( ^: t0 Q* g // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later3 |2 U5 ~( V' B/ e' E7 o5 P2 b/ i
virtual bool CheckAndRefresh() { return false; };* h; V- W8 O; n6 l6 s5 K
/ @7 ?+ j9 N% x9 c! i+ g% K# T" T
( {& d }3 T8 @, F+ Kprotected:; G- ~4 p' z- m
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
) T# z. [* s* ]; q, _, ]5 x void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);1 h, y+ h/ H" R
void RemoveDevice(CComBSTR bsUDN);
" g8 H! |9 e) [) d( |9 t0 k bool OnSearchComplete();* ?# m- o z& {* O
void Init();. `6 C; J, U) ^1 L
& A: J6 j% i6 g0 ~ H! u: T' |/ K
! x, `! z+ J9 a/ Z
inline bool IsAsyncFindRunning() g4 A% s$ `. [% k p
{( K$ a0 e% ?3 w% n5 _3 y
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
) ^2 `% X, m/ [7 {& i2 z {
& y+ W; z5 n/ E& g7 [ m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
3 W9 n {% d1 L% l m_bAsyncFindRunning = false;
" E. }- K7 b% K7 j2 d* `1 | }( V w& }% L# _+ @+ M( m7 [
MSG msg;
% ~' N2 _9 `! P while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )% X) C9 U+ P1 ?8 g- }, ~ u0 V
{
/ V& T* S4 X+ b ?# i TranslateMessage( &msg );7 T; d* T$ d* T# ]0 h
DispatchMessage( &msg );5 ?. Y J" X* L: |
}
" M- L# }, Q1 \# H: E return m_bAsyncFindRunning;+ n7 v, N9 _4 n d2 [# [, T5 V) @
}" G4 {: j" a8 @# G* h
" w/ d( O1 h E0 E
' y8 A0 y! r" G# \8 |
TRISTATE m_bUPnPDeviceConnected;8 Q I9 Q: V9 J
5 |7 k5 ~7 t5 a- P8 D
5 E4 [# v- E- Y" }+ ^/ k// Implementation! `4 E) w5 p ^6 G6 X5 d
// API functions
: e* _' ^) x/ N2 V0 }; ~ SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);3 p* Z( o# B( I5 u. k
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
1 x" b9 }- z" `' r/ C BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
! ?1 K3 `) b7 [3 M2 s# Q! @ BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);$ k6 o! k- N% F* _. n
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);- |( u1 M+ v" @0 f7 b' J
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);! X$ ^: N' r2 h& y$ I' f
# p& G% u/ {* W$ a
) e! H) O7 y9 z6 x! B* h3 q
TGetBestInterface m_pfGetBestInterface;
6 w5 ?# N V X4 E' b" R1 `7 ~; H TGetIpAddrTable m_pfGetIpAddrTable;
* ^4 c0 ^1 ]- ~; R$ m. i, ?. J# y TGetIfEntry m_pfGetIfEntry;3 v' x" `' a x, @* _. W0 {8 K
2 E4 c0 ~- H ~& k$ G; ^# M0 D! {* l; Y/ K9 R6 ~$ a- o- l: A
static FinderPointer CreateFinderInstance();+ R+ A+ e" i" c1 i
struct FindDevice : std::unary_function< DevicePointer, bool >
0 @: q# `5 Y4 L0 o {4 O. V3 Q- T Z8 `( Z
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}/ k$ e7 T5 w- K
result_type operator()(argument_type device) const
( I4 _- O5 _$ b3 w3 ^) X( b {2 b. } f1 R( v0 h2 V- G
CComBSTR deviceName;0 }6 }) O+ h& N# Y
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
% w- ^7 v, r. m$ N# G
0 B7 Z& p2 y3 F4 E* V/ l3 X0 W9 m" P! |
if ( FAILED( hr ) )8 c+ M8 q$ @) M3 h4 B0 A0 ]
return UPnPMessage( hr ), false;4 c6 _2 ?/ ]- _9 y1 i, o- C3 O; z
& j6 w. }( O+ t$ a5 n: P- \7 Q1 X0 K
) ^8 Z2 @# V( ]% { return wcscmp( deviceName.m_str, m_udn ) == 0;
B$ P+ s) p2 r% [ }# ^: s* [ v; W- r w% j
CComBSTR m_udn;' a6 y0 ^" o2 |1 _0 Z/ ~0 c
};+ } B0 B$ X5 Q& q+ R) H/ v% N: P
4 J8 {1 u! V, }3 ~# ?
void ProcessAsyncFind(CComBSTR bsSearchType);! l# w- v3 o, G
HRESULT GetDeviceServices(DevicePointer pDevice);' q3 l. A$ P& ], Y' S8 {1 I4 F' @
void StartPortMapping();. Q* d! J, o" l5 |9 O6 o
HRESULT MapPort(const ServicePointer& service);
0 ]' u# _& a% `* O void DeleteExistingPortMappings(ServicePointer pService);
! A, K- R* m# [0 F void CreatePortMappings(ServicePointer pService);0 v( c" d7 A( N6 u9 Q# K0 G6 K
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);0 Y4 [+ V+ X2 Q: F5 E/ e
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
- U' }$ S0 \( i' l2 T+ {8 c LPCTSTR pszInArgString, CString& strResult);
" ^$ D) X. q# P8 D- E void StopUPnPService();1 ~! }' q/ q2 K' `
" J: f. c& P. w
- J4 E& @) v/ W$ E; p2 y h // Utility functions
+ D7 a3 S: t$ \ HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);0 L' o5 k7 k, ?; z' e* S3 g
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);9 S! p L( _* n5 \2 O
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);2 S3 O l6 E6 @$ n# O/ m
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
0 ~/ L# q) w5 S2 z S. c HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
7 _: ?+ q& c7 u4 U) p6 R HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);7 `& j6 M y/ C4 ]$ A; }$ i
CString GetLocalRoutableIP(ServicePointer pService);
g: K) a( e: r
5 [/ i2 G6 a9 I' E3 k t5 @" f# S
// Private members5 @& C$ x+ d8 N- q( I# D- A
private:- y% w: Z! Q9 G" q# q% ~
DWORD m_tLastEvent; // When the last event was received?
' ~# e7 y5 n& y" ]0 l/ B std::vector< DevicePointer > m_pDevices;/ |/ @4 E9 L/ A/ B t: F( \
std::vector< ServicePointer > m_pServices;2 b) ?& V# k$ E2 v1 Q! ?+ V
FinderPointer m_pDeviceFinder;( \( i3 G* K5 E' y/ f5 J# G
DeviceFinderCallback m_pDeviceFinderCallback;$ \& m, [9 T0 ]3 x. \2 m
ServiceCallback m_pServiceCallback;
+ O6 T: h' q- S& D) c3 ]8 |( j$ G& r) ]
6 X3 ?8 `1 u2 x) v
LONG m_nAsyncFindHandle;
; A+ Z4 A/ F% ^8 ^: s6 g/ j9 l bool m_bCOM;
3 _ K8 o# Z2 b; j; z5 m4 m9 S bool m_bPortIsFree;
) [. b5 _( P3 W( e! s# X# n- \ CString m_sLocalIP;
$ w% r2 A* t+ w6 N0 m6 d CString m_sExternalIP;
, c1 f" j& e' g2 E- U bool m_bADSL; // Is the device ADSL?
; {4 |' d7 w: ^1 }% R bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
$ e+ K- _. s Q bool m_bInited;; y; o1 ]0 Y7 ~
bool m_bAsyncFindRunning;
2 z ?9 V: n# \& D HMODULE m_hADVAPI32_DLL;
" F5 y$ \5 O8 a" g6 V HMODULE m_hIPHLPAPI_DLL;
- |( z% K+ v1 @9 A bool m_bSecondTry;
& E1 V- g/ w7 |8 x' }: m, t" m bool m_bServiceStartedByEmule;
' E5 u' k8 D! m: o bool m_bDisableWANIPSetup;
) c; e9 c# u; F% | bool m_bDisableWANPPPSetup;% S+ x8 Z- X( o8 O5 Q D6 g3 V
( P1 a/ q, V; C6 R& s' V: X
5 `& f2 l5 ?. _% d9 ?. n
};
8 l8 |9 V" w3 ~ A6 t
* c) x" A. I2 I5 E/ `0 ]: }% x+ a. R) `, e7 N4 j
// DeviceFinder Callback
+ A+ `% g; J5 ] \2 G6 B/ Oclass CDeviceFinderCallback
3 `4 t: P' s* L' ?) l* c6 P : public IUPnPDeviceFinderCallback
* D$ ^9 `4 s# W6 T& `2 {! g{3 `6 G+ v9 `! Q5 B& s: p
public:% P; p. H- ^6 t: ?$ Z% J
CDeviceFinderCallback(CUPnPImplWinServ& instance)
, ]" A7 x) q$ [" B8 |! _ : m_instance( instance )% _ j$ D' u" J- F' x3 C
{ m_lRefCount = 0; }
( M8 r# t7 M6 j5 e; B- a. N3 \% |, R2 |
; s: D! p8 t) `8 \! n3 _$ ^: \ STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);3 F/ T a) f4 O( c9 F7 ~8 U
STDMETHODIMP_(ULONG) AddRef();
+ i! f3 d6 P+ G% @7 A+ l4 t a4 | STDMETHODIMP_(ULONG) Release();
: G, C9 G! h0 s, G' T" ?. a
7 r9 L7 @1 Z; n1 W% s( W
8 d$ H2 O) t. n// implementation3 ]* t; m0 U1 W# S* p6 V7 h; z
private:
8 ^' E3 |; L% [ HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
' t9 f: D9 e7 ~- k: t HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
/ L5 u! b) t( p3 a; c HRESULT __stdcall SearchComplete(LONG nFindData);4 S7 W* Z) D0 i/ ~
1 ^# f; B# ?$ ~, \. \! G( Z) m8 g$ t
! b0 Q2 l8 H, H& g4 M& uprivate:) L0 ^. g7 M4 ?" \8 }
CUPnPImplWinServ& m_instance;
3 `5 C, i' L; n, P( s LONG m_lRefCount;
' e, ?. J& d5 C/ e1 ~* s};. y6 r+ p" r0 q: N, x& B% O
, \" t! a; F$ M4 w( N
& l9 x( Q! {# g) v3 L8 p
// Service Callback 0 w+ w X7 l0 W* z3 [
class CServiceCallback) \: Q r4 g, q" g( u
: public IUPnPServiceCallback
7 O* {0 |! N- @' E% _{, z7 `6 M: y1 w, F5 [6 ]
public:) L% W7 s, O& F. v6 w5 N
CServiceCallback(CUPnPImplWinServ& instance)5 c# C. [0 U) q w# d
: m_instance( instance ); q C4 H# b: Q, ?, p. A0 u
{ m_lRefCount = 0; }
- G2 F) K8 y3 @$ s" k/ o2 d& V
7 M0 Z1 j/ U+ H: s" |+ s STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);$ u; y C0 E3 L9 b, f& f( k) f7 M
STDMETHODIMP_(ULONG) AddRef();
" q- X0 Q0 R/ @+ Y9 h4 |) W' ?3 A g STDMETHODIMP_(ULONG) Release();
+ h z- \- L4 B6 ]+ t Z( g; B5 \1 G# U
5 _, J$ f* I7 U
// implementation3 H* a4 q& V6 \1 T8 \& g
private:1 z L3 e0 X% W% u
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
# R5 V, ^, c* ?" b. R HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
9 f5 E6 B# f/ q# n. B( I
% _! k5 ^( I A% O c6 g; M* I# ^# d+ V
private:
3 I0 C4 P# n w+ p: a: V' h CUPnPImplWinServ& m_instance;+ J5 ]" |+ ^" O! m! S7 j
LONG m_lRefCount;
$ |! |& Q* \6 Y$ t0 v9 S% D};' b$ @- W H& _) [+ }5 S5 T7 h
$ t+ V! D, @/ A: V6 [/ L5 |) D) j, _ E& Q& V, P& j( p8 ~4 S! s
/////////////////////////////////////////////////1 ]6 `5 Q6 G2 s. d3 ~
4 S, j; [7 Q6 J7 Z: ^% b7 t
9 m8 X' [) Q" F: x+ m! l4 C( {
使用时只需要使用抽象类的接口。
, a/ D$ r! |: T" g' K* A, @ x# FCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.2 Y. ^4 J' I% O! y3 S5 T
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
/ C1 Y o1 d' aCUPnPImpl::StopAsyncFind停止设备查找.
' }/ l) I' F/ ~7 TCUPnPImpl::DeletePorts删除端口映射. |
|