|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,' Z! o6 w4 U" i( Z0 q) N
, t* j1 i& Z4 V7 \3 _: _# n$ H
/ o6 M. F; y- v# ?///////////////////////////////////////////* C6 {, a9 h4 u8 e E" |5 Q/ ~* K
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.# M; t) d I7 G
* o! r! E0 C! Z( ^' x5 U, q( l6 X5 j( K
#pragma once
; _0 l2 p3 A# N, T5 n3 g#include <exception> C% r& @, O6 O5 ~3 F' d
) `8 B& D) ?; @& @) e, ]
/ ~; W. e7 L7 R
enum TRISTATE{, Y& m( e, g5 h! i
TRIS_FALSE,
5 A$ \& x7 G+ i) U: [# O" E; _7 Q TRIS_UNKNOWN,4 b, ^2 d+ R/ `: h8 `) O
TRIS_TRUE" V) g& T2 C7 `" f7 {8 h3 c
};2 [, v6 \/ {4 o' Y
3 Z$ |6 h- R1 `- F+ D- k# Z5 x* ~
; Q# b8 x! S+ V) |& `
enum UPNP_IMPLEMENTATION{
' n( r; u! i$ q2 f, U0 L3 }/ I UPNP_IMPL_WINDOWSERVICE = 0,
" Z, k, ^# T+ F* j- i3 R UPNP_IMPL_MINIUPNPLIB,
& U7 L x6 L7 x: \: `1 H$ d UPNP_IMPL_NONE /*last*/
9 C4 j. D# _% G- I};
3 W: R5 h% ~- A. \5 N9 k3 c; S
& Z3 X' ?7 r! |. T7 q! g- Z+ {9 ]; p, G+ i. R! F" a
' C$ P, s( ^& l" A: W5 g( b \
! b/ @+ B) k% J9 Fclass CUPnPImpl
/ @* V! _1 m( _* E0 N+ R9 C7 A, A{. A9 k/ ?. v4 k
public:' p' d0 K9 t) F) M/ n) P6 W" U2 s
CUPnPImpl();
+ E, k- V- O7 ?9 C4 N% t virtual ~CUPnPImpl(); k( ^- A& S% O
struct UPnPError : std::exception {};( }7 h2 {% G& K* S$ y
enum {
: C9 ?* u* a: `% D. f UPNP_OK,
* H9 ]! B& U0 p# X. l/ A! F) y2 d! p3 q UPNP_FAILED,
# |, a' f9 S- u! w UPNP_TIMEOUT' C$ i9 U& K# S' \6 @
};
: ?9 D3 O+ @) M2 C$ \* O" ]/ C" k! _. o+ r6 u- L8 _
$ f% Y% H8 L$ j: W" C" [# J/ f virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;1 E# b" r4 m9 N `5 Y
virtual bool CheckAndRefresh() = 0;% N9 Q5 m% H. |8 w4 F# u) r
virtual void StopAsyncFind() = 0;' N& s, X" z- V$ ?& v; `
virtual void DeletePorts() = 0;
! u2 I2 _, \" ?, [# Z virtual bool IsReady() = 0;& A# U* J. }& |+ ^: @
virtual int GetImplementationID() = 0;) s# z" ?% T* `3 [" x
7 _: B* J( p) A# D( W. b void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping9 N$ b" l* u* n r7 h
& o! R- S/ [$ S" j& ]9 G) y1 V
( q/ e0 n: D, w% a5 A+ E, J; r void SetMessageOnResult(HWND hWindow, UINT nMessageID);
$ P& c( }: v; Z4 X6 { TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
$ ]+ m5 ~8 [- L i7 y0 o uint16 GetUsedTCPPort() { return m_nTCPPort; }
. V+ [$ S/ |! ~+ b uint16 GetUsedUDPPort() { return m_nUDPPort; }
/ h. m! x* X, T B+ ]0 B
6 {9 E9 I$ i4 y1 y) l& e! C$ c
( t" b/ n, c4 o// Implementation& c: L& {. g1 }* A: C- Z3 e' P
protected:
2 O2 N1 @; X1 c$ ~% k1 J# e3 K! E% m! ` volatile TRISTATE m_bUPnPPortsForwarded;
* U i- W* m) q# G; R void SendResultMessage();' }7 r1 E$ R* M# L: O
uint16 m_nUDPPort;
+ {5 b7 O6 @% s# I$ Y) p uint16 m_nTCPPort;
$ p# U9 H3 ^0 h. a/ w uint16 m_nTCPWebPort;
% X3 o. r8 D& N7 Y% R m& J/ U bool m_bCheckAndRefresh;! z5 ~' h, K+ G/ U, T, V( i
* L5 T: V7 ]1 g7 q
3 q; J* D2 d$ d
private: ]0 p; M6 D# ]+ Z' y" I
HWND m_hResultMessageWindow;
, O5 M C4 l \/ x$ l UINT m_nResultMessageID;: J8 U2 K) {( D3 g& i6 j" L& D
! r5 X8 `: ^8 s
6 U5 X2 m+ u9 I$ P% j};
$ [$ G2 G3 E+ x& [; P# c7 Z4 I* W, t
$ \$ }2 M0 z5 ?6 D' \% H0 F2 \
// Dummy Implementation to be used when no other implementation is available0 J& }) N5 `; C* T# x z3 g E
class CUPnPImplNone: public CUPnPImpl
1 D+ {1 m" B" [ r- B{' e- b6 N2 P; p& i O, Z- E1 f0 {3 d
public:
* r; M5 B: L& m# h$ m4 L1 g virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }* u& E. H f; Q, i. ^4 E! K1 D7 Z
virtual bool CheckAndRefresh() { return false; }
; S. ]" g8 V& n3 Y s5 b* L g( l virtual void StopAsyncFind() { }
3 H. v o+ L/ ?) k, } virtual void DeletePorts() { }; }1 ]! d0 }& p+ s, ? l# Q
virtual bool IsReady() { return false; }
. Q. w; Z2 F. p5 r' t* \' W virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
1 S* P0 v Z% e4 H4 }& C};
# q% ^. ^9 D! I6 Z3 J O
% V' H$ Z/ W4 Q
( K0 @9 E* C" ?2 y/ j! _/////////////////////////////////////5 j; X1 P! B" o9 N
//下面是使用windows操作系统自带的UPNP功能的子类9 F, T+ n: ~- d0 @' r+ D* z
& e3 \3 ~4 c/ Z! S( ~' L
- X: W! D: k' E0 V- N. j+ W#pragma once
8 g0 x& R: G9 k! o. ]' }) M#pragma warning( disable: 4355 )
0 Z4 ?0 v$ R- f8 g( U9 v
' E. M+ z& G8 m- w9 W* A& [7 `$ s1 _7 G5 o
#include "UPnPImpl.h"* B/ ]. @4 T; y& V% n
#include <upnp.h>
( N2 ^: X& g* j5 T8 i4 z! Y#include <iphlpapi.h>
( x9 H" E4 x8 B( o1 l#include <comdef.h>9 e2 R# G# v! m: a2 k6 N; g
#include <winsvc.h>
! U. A3 H! d6 _! d1 r% T* x. }) `+ N5 d3 v7 ^9 f
9 G$ M9 K8 z6 j! \
#include <vector>
( t( o% y* C6 w#include <exception>$ |+ X) J. g# ?
#include <functional>. H; F! U# ?# F: ~
/ _% i8 O7 o7 [6 f: c4 X( ?5 t# ?0 n) X# F" j' j/ ?, Z! N6 {
* q0 p n3 s+ ^% \
3 `) [ v8 ~! O1 ?typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
T: P, v- \, @) r+ Ttypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
( e+ E$ q% v8 W8 }! e# Otypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;; C z1 V' p# F/ S6 U% R0 F: y
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;9 e; [* Y9 s- D
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
+ b# P5 m4 c- Htypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;1 q$ K7 c7 L: x9 i$ `
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;) B1 z0 [# h! m
W5 L, s& _ ~4 Y
7 N. a; e/ i0 {& @4 b H) E
typedef DWORD (WINAPI* TGetBestInterface) (5 g+ U4 _2 B) o! R/ Q/ x; Q2 I0 k
IPAddr dwDestAddr,
. Y# {, [/ X2 _, _2 c# a# g* Y: v; `2 U PDWORD pdwBestIfIndex
$ o0 c0 B7 d. R; o% p' O* @);* X* D# X( Q, f8 b9 ]/ }+ S
1 Z6 n4 b- N$ D3 }* a+ s$ K/ R' m" v9 e0 {) z
typedef DWORD (WINAPI* TGetIpAddrTable) (
% Q0 l. h. X2 W PMIB_IPADDRTABLE pIpAddrTable,
0 u. W8 P$ N6 R- o PULONG pdwSize,& f0 b) s! r. |/ @
BOOL bOrder6 A1 T7 J+ W* y" E1 z
);
3 H; l' I" A8 h j3 T; q2 K: Y7 U$ ~ P; c
. x& P* h+ `' \. J o2 Etypedef DWORD (WINAPI* TGetIfEntry) (0 }0 g/ \: f) y7 m% m, H' Q' p! l
PMIB_IFROW pIfRow8 b5 @+ T( ^; I
);
% v+ ? J4 x. C) u8 h* b0 {" m( |/ U2 G1 B
0 P. r( F) `3 E, B9 C8 l, g6 V% I
CString translateUPnPResult(HRESULT hr);
: C+ C5 o6 {4 v5 Y; O3 s( B$ BHRESULT UPnPMessage(HRESULT hr);! G7 J9 ^0 U' s3 y8 c
# L: i& f( N4 w8 H" x+ y5 \5 N( m: Z ]! F3 C! h
class CUPnPImplWinServ: public CUPnPImpl
8 ~8 U5 J2 v3 x) e7 H{
( G" @, ?7 q; i- O: s+ j% l k5 a friend class CDeviceFinderCallback;; }% ~1 ^0 ]# Y0 s$ `. K- K8 r
friend class CServiceCallback;0 q- u |4 z; ]! N* ?5 f& j
// Construction
' F) C4 m1 H/ Z. dpublic:
5 Y: I0 v: U9 u# x4 j virtual ~CUPnPImplWinServ();
A1 {- f$ s% _0 Z1 Y. W CUPnPImplWinServ();
" g& e, Y* D* n- q/ n& I$ L- `
/ k7 A8 Y' [% \" M1 n* K
. T1 z" L: Q( B, |* M virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }$ }+ a- E `1 p/ Q9 T
virtual void StopAsyncFind();4 E+ z+ e+ }1 O3 e1 J8 g: S3 X* ?
virtual void DeletePorts();/ _4 F U* Y- I! [ r9 t$ W* r
virtual bool IsReady();9 P* Q: r$ A5 W. o( C1 k
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }, H3 p/ K2 ]# c2 I1 j8 j* ~- z
: @& N4 _; A! s0 W3 k- m& m6 J' e* g+ S& A3 ^: g
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc); z7 Q* \ p3 f; G0 Y: F
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
2 ]: G2 J* `! x* U% c virtual bool CheckAndRefresh() { return false; };
% O1 z, D- l6 V
' x. s4 l4 B+ u0 s1 K$ S5 C
; i$ y- I4 d, a8 jprotected:. s; J* K& I$ V* H( D7 {* F+ `2 x) `) o
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
- n4 m: ^- N) c4 Y$ \/ E void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);5 q1 x, f) ^6 \
void RemoveDevice(CComBSTR bsUDN);5 i" _2 D8 p: \4 V# U- `
bool OnSearchComplete();8 E/ m: B- H9 U8 q- f
void Init();
' s, M0 D- p/ Q% ]; n0 @5 M: l! C: |6 b3 W5 d* b/ O( X" [
4 R: ^) Z0 _- F1 p7 s( N& u inline bool IsAsyncFindRunning()
2 Q) B F5 Y! O. w( m {; H! E2 M D- J4 a3 E I5 t
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )6 O$ _ c! i. A2 \4 N9 a% P
{0 ]5 L/ E9 O4 {4 Q& ~
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );8 |; r: X) [" U: U7 r" u& t0 A# d
m_bAsyncFindRunning = false;- h2 }1 f; m9 o8 q$ u* N
}
; D. w4 N( G9 Q) V8 z# b MSG msg;1 F) L7 `* U) D( q
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )8 S! E! S# c! h( T% v3 U/ c2 M+ P
{0 R1 c; R5 M- m
TranslateMessage( &msg );; u( ]9 k6 a* a! ]
DispatchMessage( &msg );
, x1 q- X# z5 [% J) X% u }
0 y- g4 f3 H5 h$ ~5 b return m_bAsyncFindRunning;
N/ b# ?5 o1 d1 q, {& A }
/ H& d3 s9 \4 P1 ^) b3 X. v0 r, h# {- c& G, N2 G
; {+ d; E7 `; A3 c9 p, P TRISTATE m_bUPnPDeviceConnected;% Z- ~9 a5 Q' b( L- r/ s
" m0 u3 u4 {+ x3 i: G* F! B; [* {0 _+ `$ E8 f
// Implementation
7 U4 p$ b* O4 B D // API functions8 ]8 U( B# Y' v* Y2 u! x; I" `
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);# U: S: K. C! I7 x5 s. Y
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);* H) H2 k K: @7 d, Y0 o$ i
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);4 V1 o' d1 D: _$ W2 s* _. ?/ _ d
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
/ ~( z2 G6 \ o9 L% s$ |+ E BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);& J: p6 l; g+ m* {: S
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS); j* \- { m" \# ?2 s6 y
, N" T3 t q- D( ~: b* O; U0 H: F: T
3 W* Z/ A. |; p @" b! C& ~
TGetBestInterface m_pfGetBestInterface;4 \2 C# ~) @4 r8 X' e; r
TGetIpAddrTable m_pfGetIpAddrTable;
- p' o! {( G' q+ y TGetIfEntry m_pfGetIfEntry;" E: A9 n7 \1 P& \/ S" |
/ ]4 _2 Z! ]7 a8 d) j8 Q( r
- @: W3 M% ]; e static FinderPointer CreateFinderInstance();( ^ \0 h: i2 ]# R* y6 ^; V M& p
struct FindDevice : std::unary_function< DevicePointer, bool >+ l o# p' N' p' u- ?8 E
{
; Z* C' p: P7 c, p) M FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
- Y5 l& k6 A" P result_type operator()(argument_type device) const, @% h2 {" s$ o) ?$ p
{
: b4 }6 A! B8 V* P1 m6 d6 v CComBSTR deviceName;( N- n. l }2 Y; j7 Y
HRESULT hr = device->get_UniqueDeviceName( &deviceName );% c2 S3 p E3 P
: T% d: v v+ l% E% @) Y
) |8 X+ y7 D7 X' T: @ if ( FAILED( hr ) )
9 T7 [; d/ ~( v' p1 C6 ?' A return UPnPMessage( hr ), false;8 {6 Z- N4 M! M# K
7 l) H X7 P$ ?- F5 w8 {
# L7 T) C8 j; h- Y8 s, E# p return wcscmp( deviceName.m_str, m_udn ) == 0;
" O& u( D. r- O8 J, ~ }% J, x- A7 Y, X. j4 e4 t0 Z
CComBSTR m_udn;/ e2 V! I9 x; N5 R" Y: Q- c* ~
};
/ n6 j/ |! T: o! B 7 |' z& Z- f+ ^
void ProcessAsyncFind(CComBSTR bsSearchType);
+ O/ N6 S: `% a0 u6 |6 z5 H HRESULT GetDeviceServices(DevicePointer pDevice);
9 d9 Y. C. x U. _- g void StartPortMapping();3 {! K/ r. p5 n8 ]5 b( _
HRESULT MapPort(const ServicePointer& service);/ r% T1 E8 f) }& m
void DeleteExistingPortMappings(ServicePointer pService);
0 ^1 b/ m) r+ {+ l) ?! q# Z void CreatePortMappings(ServicePointer pService);& d+ W9 a* \: E, a" Z1 _/ e
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
, |0 E; w9 t9 M ^% ~ HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
* v7 ?5 r% `3 j* l/ k9 m6 R7 S LPCTSTR pszInArgString, CString& strResult);" t+ N( D. u* S; e( M
void StopUPnPService();
3 v* F2 m5 o% h2 o5 y
/ i- T( E% B; D7 j F
$ f Y( n3 [5 j- y8 A // Utility functions n+ `, k a8 Y$ h) E$ |. O/ u
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
0 h6 }' R, n' I0 D/ ~, i1 D INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
) i/ D7 q% l0 |8 T; j1 P INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
* N% Q. x4 C; D% V void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
9 [0 \; t; ]& N) z HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);; Y8 \% q! a9 q. w) _# `
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);; F4 T1 S- D2 j" p) V& y
CString GetLocalRoutableIP(ServicePointer pService);
! \8 w0 E1 A M/ W5 o: J* d2 p6 L% h, w
% x. m4 K( S# U% d
// Private members
4 ?4 z* W) @5 v5 Jprivate:2 ?9 G X" ^ `, K$ W
DWORD m_tLastEvent; // When the last event was received?# G C; O0 K& t6 d7 W
std::vector< DevicePointer > m_pDevices;; ]& H+ V. w1 \6 d. }4 O4 r# a
std::vector< ServicePointer > m_pServices;; P0 Y1 u- z& M c
FinderPointer m_pDeviceFinder;% W7 z& z! ~ {' Q. `
DeviceFinderCallback m_pDeviceFinderCallback;
( n: M( E- P- l2 ^& ^ ServiceCallback m_pServiceCallback;' F6 F" f) A) X& v, m
8 q9 p3 g7 u- j6 B/ l5 a
) ] n& p; V, N. F& M! P
LONG m_nAsyncFindHandle;
; ~9 R4 f# {/ M7 \8 P bool m_bCOM;
# ^2 d) e0 n, j; k$ I9 y& B bool m_bPortIsFree;
! _( u& H6 A* q ] CString m_sLocalIP;
; n! a' J0 ?5 d/ P- H' ? CString m_sExternalIP;3 @( j! O) L$ l
bool m_bADSL; // Is the device ADSL?1 Q+ d( z5 c$ u7 r# j6 K& x) P+ o
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?: L( z0 g2 {" a; H; C1 R; Z
bool m_bInited;6 }# T% ?. L: E' C* _# ^+ ^' v
bool m_bAsyncFindRunning;
# ]& Q% G5 V7 d" J4 T HMODULE m_hADVAPI32_DLL;
; n# x; ?* R6 z HMODULE m_hIPHLPAPI_DLL;
; G& K9 f0 q/ q5 i2 \/ ~! v1 g1 U bool m_bSecondTry;- U4 f( |2 C8 }# c! T3 g$ d& z! K% E
bool m_bServiceStartedByEmule;
: T0 r' A* T5 `6 Y; R+ k bool m_bDisableWANIPSetup;9 I8 ]& S7 E- j( F
bool m_bDisableWANPPPSetup;/ ~4 B8 R- D$ h4 ?# g
. M% M% V/ r6 b1 d9 C
5 s% P# h. k, o) A1 r8 {};4 O) O, M6 `9 _; d$ D3 d( i* c' G
8 f, V& i# D. M, B8 D8 O, ~1 T( X3 P) g+ c
// DeviceFinder Callback2 S* U! k1 q( g! q U
class CDeviceFinderCallback
, F K- Z7 k( _8 [- w5 T9 l( _ : public IUPnPDeviceFinderCallback8 c4 r: q; p8 K' U# C9 r$ R" ]
{. l3 v* K+ t' t6 u
public:
$ _" G9 D O7 f. H0 t+ C CDeviceFinderCallback(CUPnPImplWinServ& instance)( O( N7 S* x4 J0 ?+ }
: m_instance( instance )) [3 ^* N1 F S: e" b1 k+ g
{ m_lRefCount = 0; }$ ]3 V2 e G6 T1 X v- a# r
- s/ l% I- L, V/ K
6 m& W/ j4 l: g+ D9 p+ Z( Y STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);9 Y: a. ^7 Z) A% F" ~/ G9 G
STDMETHODIMP_(ULONG) AddRef();
2 M' j' V8 [ K' w+ C2 Y STDMETHODIMP_(ULONG) Release();
, R2 @, n! c8 O, K5 A1 b3 B2 d! B/ k/ y' P1 W
& M9 l& }& L* J- E4 R. @+ p// implementation: t, P+ F& G0 \# y4 Q6 g7 Y# p+ {" @
private:
# {! ^ |( Y4 K' b4 C) o HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
4 {( N, v* X* i0 { HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);% W, ~& O6 p' N8 I) @0 y
HRESULT __stdcall SearchComplete(LONG nFindData);0 e/ ~0 R1 q; T$ x7 p; @* N% e
: M/ L. x3 V c% L$ g
1 M8 `$ P% v0 U! Yprivate:2 H* ]9 p+ P5 Y, [& ^9 u ~' }
CUPnPImplWinServ& m_instance;! ^' G2 h" Q- O. w
LONG m_lRefCount;
& f" d) C& C- M0 }/ ^/ ^6 h};
' j8 A0 U( g+ W0 P3 N' g1 ~1 \
( ]0 D! h( X6 V
1 E% q4 N7 j2 n: a// Service Callback
" ]. P- T- J" V5 C4 L' a+ d8 mclass CServiceCallback
6 L7 E) L) O. g K8 C8 d% }4 l7 I : public IUPnPServiceCallback
9 e' `0 _/ L# i5 D{$ v A, e% `2 g. H& f, @1 T
public:
. z7 j: j$ f, f CServiceCallback(CUPnPImplWinServ& instance)8 f/ L! `) A6 M4 @
: m_instance( instance )
. D7 X0 p# r4 y9 z1 @7 h { m_lRefCount = 0; }
. }; N. I* ~+ w' v
4 y* S! g- d7 T STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);( @4 ], V/ @9 w
STDMETHODIMP_(ULONG) AddRef();
" U3 Z$ g& d$ _( a0 \8 A STDMETHODIMP_(ULONG) Release();
" F) K: x$ |& k# p
5 N, F" K6 M8 U6 A7 _
0 g2 o8 U! }' p( Q9 Q// implementation
) U" i; s9 z& \7 L7 Nprivate:
& g4 R$ R1 \0 w HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
; q! Y2 k3 m8 f! u HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
1 U5 s) ] P5 S. g$ [6 L) }3 [% ?+ K' P7 ~" O
$ o$ n' }! j7 ^, t! L3 y3 Q0 N) C
private:: K1 w/ q$ a3 s& J9 {
CUPnPImplWinServ& m_instance;
* N5 w5 y- x7 b$ ]* |( l LONG m_lRefCount;
4 w) \# D' h7 t1 r. f};: k9 V5 H& d9 ?6 n4 U* o; K3 U
9 f* Q/ [! Y! j6 ?$ |7 Y
# M8 a6 V1 x( ~. s2 B- ^0 Q4 c/////////////////////////////////////////////////" z! {! z$ T$ g F* |3 M" r
# T$ [. c9 S7 J( {* h" {# t, o6 u
) X5 q4 h* ^$ B$ B4 y
使用时只需要使用抽象类的接口。
/ P/ a+ G6 f' w* ^, s* I6 I) |CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID. n6 Y w' u3 X( ]5 R# F- r, n0 s
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
2 C5 `, X% e8 E3 d& D' OCUPnPImpl::StopAsyncFind停止设备查找.4 ~1 Q- D8 O$ V3 d6 W& h4 E
CUPnPImpl::DeletePorts删除端口映射. |
|