|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,# B9 F* E* \5 I8 j3 b
4 v& r1 a: l, L
% P7 } U& H7 i# x* \7 x/ t///////////////////////////////////////////! o( Z8 h" q; G1 m# b1 J$ L9 w
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
4 W- Z2 }1 M& K; H5 |7 B
; k3 n* i2 @) r$ ^: `& @, ~7 I5 K9 ?! a
#pragma once
6 ]0 \( _# U3 Y: Q6 G7 a! S#include <exception>
# j+ F0 W$ g8 P3 m/ d0 u
7 f$ r2 B& I# z8 T! o# N7 [2 o3 v# Z% B ?0 j8 g4 e( _: f9 `
enum TRISTATE{% E& B- @+ I( _/ g! P+ P. x: I; U* o! l
TRIS_FALSE,
5 c# G( k! }9 X TRIS_UNKNOWN,
. K& {* X X5 v9 Z: s TRIS_TRUE, m$ \4 M- v; }2 l6 ^* L
};
7 K' I' J% p- S! c* W w! K: s8 L1 \- u3 h
: m3 L4 f% \' Q
enum UPNP_IMPLEMENTATION{, E" b6 Z8 W, B4 Y5 [
UPNP_IMPL_WINDOWSERVICE = 0,6 Q( `9 k+ w9 S% l0 q
UPNP_IMPL_MINIUPNPLIB,) @+ f( w4 U! k* o
UPNP_IMPL_NONE /*last*/
9 V. R0 u2 k# E( ^/ a0 i};0 l( h9 ]. T% z: h& w- k+ ]! u" [
1 t+ z8 n, o! u+ @1 ]3 z s9 }* F6 U2 E/ z- M( _! X0 t+ N
9 D" R5 e9 ?3 ]% `1 L* d6 ?
' ~8 J/ \7 E6 E4 S, Dclass CUPnPImpl
0 _( C) R; g# x{3 B4 P2 ^1 U+ }5 q. `" e
public:6 o: _; g* u G/ x H7 C
CUPnPImpl();
7 f" I( W9 O8 Z virtual ~CUPnPImpl();
3 h2 r- a5 T# i0 C8 k/ N0 u& M struct UPnPError : std::exception {};
4 \3 M* Q3 g1 q' i4 k. F0 a: x enum {
4 r2 ^ L& S) Q. F9 ? UPNP_OK,
+ v( @+ R' \& p5 q1 B4 G' Q$ ~ UPNP_FAILED,
- Y6 K8 B3 c1 W& M UPNP_TIMEOUT
% e4 q5 Q; K6 R- @6 O5 x: p! }* [0 x% a };8 H9 R i* l g
3 M' w3 N; r7 v0 {/ m5 f) y/ r
2 c) ^) j/ i/ q' j/ Q7 x virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;& d3 F. U& H3 D/ i) Q
virtual bool CheckAndRefresh() = 0;
' w: \# n( u6 W! X% z9 x# T virtual void StopAsyncFind() = 0;8 g: c% m0 W1 A X
virtual void DeletePorts() = 0;
% O# L' a7 E9 u! p* k( O. l$ l0 M virtual bool IsReady() = 0;
7 ]% r: a% @0 x; d5 d' l* @* ^) A virtual int GetImplementationID() = 0;& Q3 m0 g0 l+ B: P3 a0 ?! B! E# t
% K7 i2 J' N5 Q5 C/ b: } void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping3 n7 P# Z. M- D% [' K! ?( ]( f
& r4 c% i5 [5 P& U. b& p
& p1 E* n) r/ U+ P; n ]5 ]. H% A* y
void SetMessageOnResult(HWND hWindow, UINT nMessageID);; ~" S3 _5 Z P3 X& A; w% O
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }. |- Q$ c% S2 l$ |* V# L {6 P
uint16 GetUsedTCPPort() { return m_nTCPPort; }& w! E& R! J8 }7 v
uint16 GetUsedUDPPort() { return m_nUDPPort; }
- B" X9 N- K7 k# y# z9 {9 G
1 y- U& |" A. k; y
6 t) d3 h2 }% N// Implementation
) K8 i# S; |! l$ D' d) J( Tprotected:7 G# B, k9 `. s$ V/ x. O+ ^; {0 a
volatile TRISTATE m_bUPnPPortsForwarded;- [- O* H* ?- C1 j" [- z1 ?7 U$ c8 L9 {
void SendResultMessage();
& G* K- M5 m- N. ]+ A' d# K5 ` uint16 m_nUDPPort;
* T0 P0 F" Y' t- A( Z% F! K6 y [ uint16 m_nTCPPort;) K# V+ w* J# F0 X0 h) Z* x0 z
uint16 m_nTCPWebPort;
4 [4 g6 G; f* H( c7 l$ Z5 f( I bool m_bCheckAndRefresh;
( C! M& j. x5 G+ V% V: f- @. Y8 J4 J$ X( r7 e' C* T
J! S) Y9 u; x. ?- @0 [private:
: b$ r' v0 X8 S+ c' | HWND m_hResultMessageWindow;) `: l7 s* J! I7 I/ S
UINT m_nResultMessageID;$ ^0 y, y/ b' \
) u! h5 Q1 ]: c. h+ }2 O
( U$ F9 N7 z% X& \- B6 D
};
, j3 {9 e$ l; b1 `
; c) X, F+ @* P- P/ Y N4 d" V. a/ @- E! \, I: X
// Dummy Implementation to be used when no other implementation is available! Z0 w6 J c( R% d" f$ r& y
class CUPnPImplNone: public CUPnPImpl* }, ]+ ]" C' ~: M2 x, d8 G
{' ?! R- m* M' R8 x+ m
public:& S& z3 J' X2 s, I( [
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
* |: c& K) h6 n! \+ C! [ l+ f virtual bool CheckAndRefresh() { return false; }2 t" \9 m( a& V
virtual void StopAsyncFind() { }
- m! Y7 p. a! h: O virtual void DeletePorts() { }) y5 ^- F( V& B& z2 F V. D' N
virtual bool IsReady() { return false; }4 ?5 e' m5 q m2 T5 k
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }6 S% o/ V) f% [
};& a5 T3 L$ O/ c' Y) `. N
% Z2 }( i' f# Y1 q+ f
4 l2 X4 V1 F5 Q* o. q+ X
/////////////////////////////////////' h: q6 [( }! E" ~- f
//下面是使用windows操作系统自带的UPNP功能的子类8 U$ A) I9 R; l/ `# l; c* R
& B) F4 ], [; U0 K: ?
1 _# Z+ Y6 ^% K! J( a#pragma once
( |* ?- O6 }) W i#pragma warning( disable: 4355 )$ H8 J% x4 L* m, R" r/ P
; E* q6 q3 n* S- `1 o2 H
3 ~2 V$ k6 @# M0 n' ^" N( B3 ?% v
#include "UPnPImpl.h" U: X4 Q. |1 c# j
#include <upnp.h>0 @0 K+ d; T0 L y1 I/ J
#include <iphlpapi.h>
& G3 z2 h9 u: r3 c- I+ n#include <comdef.h>
+ F6 X( k. O# N$ o#include <winsvc.h>( f8 C: l: Q% K# P; w$ R' R3 v
( R5 A$ K$ k+ @( K# g$ x# h
% R+ b( O- b# W7 S6 s; `, ~#include <vector>
/ c7 q d8 |0 L1 U# f5 b#include <exception>+ N4 `& P4 {* Q6 [
#include <functional>9 t& i7 N; ]. O/ B/ F: y. O$ s
, M7 e& v B' L7 K2 b+ ]7 R* X+ q3 H6 l
& \! S+ H' W0 O# G( q8 Z) B4 e2 v' B* e0 q) X" L
7 o. g! Z& {" n$ O0 Otypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
- l6 g/ b) [' o, r# m, Ztypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;% x2 [# P" @8 O$ D* J
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
; R2 s# H0 w! I4 p; H, b; L" ntypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
0 h E' P3 ~. Z- @typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
. L* ^/ Z7 C7 F* Z3 E2 e- ^5 n8 _8 e" D! Ttypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;7 C6 p1 K6 i* z4 E
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;( U0 W* G4 T/ D/ [
7 ?; P" _6 z/ P" u
: y6 W7 E9 T; D
typedef DWORD (WINAPI* TGetBestInterface) (- V5 |. E: ~. e; G a* }: Q' w
IPAddr dwDestAddr,
' t- _6 G: Y3 V& u: z$ G- h! D9 i PDWORD pdwBestIfIndex0 n6 ~. t5 Q$ Z _9 |
);
* W! W5 E; g- O+ s* u n* q. }8 S/ h0 P) i9 G/ z
! c9 H8 R8 e/ N0 T& m0 stypedef DWORD (WINAPI* TGetIpAddrTable) (' f) X9 n* g' e. G( w4 X
PMIB_IPADDRTABLE pIpAddrTable," r9 a7 f6 X6 G3 A; `$ z
PULONG pdwSize,8 \: C1 V. [- F4 Y( Q1 S
BOOL bOrder, r' _ {, `! U! o2 d/ g
);
& y: u- |8 y6 w! k( I' M* r" m2 |* j' p! E% ?2 r
. z+ F- }8 E5 u" b) ?. a' dtypedef DWORD (WINAPI* TGetIfEntry) (+ j- T3 t# e K. l3 W' P) _6 c
PMIB_IFROW pIfRow
" M3 Q: k& B1 z) h% i);- ?, W: \! r t9 z N& k# x
: O; r; T9 _# O6 n+ C
% X, u/ `2 o+ X! N Y: _CString translateUPnPResult(HRESULT hr);3 r ?$ o" Y' }# L' h' F
HRESULT UPnPMessage(HRESULT hr);
2 f4 U' ]1 I) z
8 T) t" j1 F) ~' t2 c8 S) D# V- M' c# Q# u
class CUPnPImplWinServ: public CUPnPImpl
1 {7 y3 g6 R1 t% u) `{
% B- o+ J/ ]. T* h5 r) E3 X/ W friend class CDeviceFinderCallback;' u7 e) m& w! w; Y; v l( G4 l& g+ C/ [
friend class CServiceCallback;
. T3 _& e0 W7 d/ d: v. `2 {// Construction
7 C- ?! p! k3 f8 _3 l& L2 t1 epublic:6 o8 h$ c$ \9 N F6 a" ?+ N- j
virtual ~CUPnPImplWinServ();# `$ x+ h$ ]+ Z6 I3 p% t) D
CUPnPImplWinServ();
1 v- M0 W _" M# P( X2 U
# h% q+ J r' _4 W" e& u& |5 u1 p# h
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
3 O6 E8 G# y! l/ T) C# S virtual void StopAsyncFind();/ i+ n5 o5 P: z; R3 \% Y& h
virtual void DeletePorts();
' j5 D5 c$ R O( p virtual bool IsReady();9 }& X- b( v/ H" n" r* L" Z
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }; p+ c7 x0 b* P/ e& ~( D, b
. [$ T9 k1 g4 ]
0 H% a: q$ A5 D! n, { // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
- h3 g# B; O9 X' i // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later7 f' z% L5 ?6 l' n2 ]
virtual bool CheckAndRefresh() { return false; };
! ~$ q( `6 \) J( E% _* Z6 G$ b% G; c$ D! T" C3 U$ B. E/ v) Q$ t
3 p: p, B2 h4 ^7 L$ z6 T7 O
protected:
, K' S$ K2 T, G( U* v/ H void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);- h- X) v( |5 t; W
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);. g& K* l) ]4 M" F6 G( I% Y/ b
void RemoveDevice(CComBSTR bsUDN);' { P. P# z; w4 |; w
bool OnSearchComplete();; {3 N0 }; L) ^+ V
void Init();
# ` N9 H+ {. s: l5 R
j3 H5 ?6 @! T( a- b0 B
' M; _1 Y' Q+ e0 ]& Q. ]8 t) K inline bool IsAsyncFindRunning() ! p: `1 M9 D# G+ s, L5 {& l T& s& {
{' ?" @' ]& B& R4 p8 ^
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ); Z) C1 y5 y3 d4 a& |2 V
{
5 z8 F2 J* k! K m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
% e2 V$ F, g( H2 e2 f0 R m_bAsyncFindRunning = false;
" X. T8 Z( Q7 C: H, { }
7 F! C9 `8 ~$ ^- z2 Z% }# e/ u* s MSG msg;; C8 M2 q/ L* \, R: I6 n
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
+ r+ S' x. F) [' ] E' r% o+ v {$ E4 l4 d% r3 u/ I( z- J `3 O9 i
TranslateMessage( &msg );
4 c: g3 G. l. y4 V DispatchMessage( &msg );: [6 {* y; v# V# p7 \4 N. R* k8 D
}2 R0 k9 j: i" y W$ v
return m_bAsyncFindRunning;
) N2 D% v8 v% L/ \3 U; K }
8 ]7 f! ?! z) S2 ~1 k5 Q: V) C' u+ k# u2 o/ t) G
( e0 Y3 E' Y2 I
TRISTATE m_bUPnPDeviceConnected;
$ q( @' x% s4 j8 H
9 K0 ^# V; o# p# k4 P8 y2 D1 k1 ~+ Z- c
// Implementation
* D! K& Q( l3 k) k9 w- c // API functions7 @% n! {- z u
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);( |2 J0 `6 q) P; Z7 r! O1 B
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
% Z9 e# Q0 N x# K( k! ? BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);" g8 }8 v& Q" x9 d
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);; ]1 H+ Y( p; _$ V; a
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);. O4 r6 E/ X T; \; R/ O+ i
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
; V/ j& t* Y' ?: t" N6 g9 `% O6 Z: I
( Y, q6 |# B$ B9 @ TGetBestInterface m_pfGetBestInterface;
3 N9 d2 ]/ {* S9 j5 I; T TGetIpAddrTable m_pfGetIpAddrTable;' f# P5 H" u* t$ A7 _ c
TGetIfEntry m_pfGetIfEntry;! F8 J" G3 V9 J; V
( c6 `& s- o; P+ `5 v* d
: Y1 Y0 \. F `9 l
static FinderPointer CreateFinderInstance();7 g; @4 ~; a2 E
struct FindDevice : std::unary_function< DevicePointer, bool >, f' s# n4 x# y! H& Z% s
{
3 y# C& @# G U! i& T0 l! m' @ FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
5 l7 n7 r- e! K2 B result_type operator()(argument_type device) const
. ?% v, c5 a% g4 n3 R2 D* J! | {
# L: k! {% v) M3 R; z0 Q CComBSTR deviceName;
+ c) j& D" |4 X, E7 p# `" V2 ? HRESULT hr = device->get_UniqueDeviceName( &deviceName );$ {9 u6 p# t# T8 e/ ?6 ? E
$ [- e" v: d, a* u1 P4 y
/ ?+ i1 ]& ^; A$ q if ( FAILED( hr ) )& U) u+ N* }/ P! e/ t4 T0 }! \ n
return UPnPMessage( hr ), false;4 N% y; t% n4 ?. o8 L, k$ D8 |. J6 q+ U
# E8 V( R* d" y' S6 K
8 |! |9 ]6 ^1 N" u" E$ P return wcscmp( deviceName.m_str, m_udn ) == 0;
" ~5 Y) U$ p# M: v" g8 ~ f$ a }
+ Z n2 h8 W" M2 Z- C CComBSTR m_udn;
' Q @, y9 H7 B, F };
3 y/ W6 q" o1 D2 L5 [6 e0 m: ~ , `( E K7 D# i" j8 Q" i
void ProcessAsyncFind(CComBSTR bsSearchType);
) A3 r2 z+ h. F6 x' r HRESULT GetDeviceServices(DevicePointer pDevice);8 h9 N$ m0 L5 U) K
void StartPortMapping();
/ B' q2 b2 y8 \1 [- J0 R HRESULT MapPort(const ServicePointer& service);
) @' j7 Z& L- J void DeleteExistingPortMappings(ServicePointer pService);' |. p# A9 M- G; W
void CreatePortMappings(ServicePointer pService);' U* C# v; z) U9 O
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);2 Q$ A' G6 U8 A( R
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, # U9 Q* t- u R, k I1 C) L7 M1 ^$ {
LPCTSTR pszInArgString, CString& strResult);% ] N3 K. C2 |2 K/ a. h+ K' R' F% h
void StopUPnPService();2 g% e3 A; G) t; A. X9 ]0 ]
( S& c( c% z; E" j, {
$ N0 ~/ a- g+ {) y# C; P; } // Utility functions& w" E; L" B! ~% a
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
5 F {) e+ K' }- p/ T0 v6 O7 d INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);% A9 N! O9 G$ u8 _
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);# ]4 K2 j4 D2 v* Q
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);2 H9 N# s! Z2 a
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
1 B5 I& Y3 F& D4 W HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
/ U1 ^: [" U$ R$ R- J+ c- c CString GetLocalRoutableIP(ServicePointer pService);5 b/ q( F0 Z) {
+ S3 \$ X9 |/ z/ k; b3 `" f, b
: E3 O! _( D7 ~( U2 R// Private members/ Z6 w* _! t( [9 d4 v! O
private:8 S. l8 \4 N2 i+ e1 x+ [( t2 ^
DWORD m_tLastEvent; // When the last event was received?. E% R& j+ u2 P
std::vector< DevicePointer > m_pDevices;6 s+ X9 ^5 |! s) A& I0 D
std::vector< ServicePointer > m_pServices;
! Q8 o' l8 W1 W) ^4 } FinderPointer m_pDeviceFinder;
; V: L+ L7 L I R/ ^: a DeviceFinderCallback m_pDeviceFinderCallback;
6 A# E5 j0 z: s7 N) J, G t% \# s ServiceCallback m_pServiceCallback;+ ^! V% K! x" Y7 f
# r- B# [) D3 t' c. j$ ?
7 s5 ]# }+ i! i( d8 W7 ^ LONG m_nAsyncFindHandle;( y2 d5 v' O x
bool m_bCOM;2 Z* E% D4 U b5 m. k- ?- f! J
bool m_bPortIsFree;/ a4 l4 g& K: X5 [
CString m_sLocalIP;
" ?2 G! w0 O+ k# _+ Q/ }, s8 ] CString m_sExternalIP;
6 u9 q& F, l4 L6 E% C bool m_bADSL; // Is the device ADSL?. |3 |# J! o6 d
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?9 @- S# o; ?; `& c4 [3 m' N/ r
bool m_bInited;- q3 E( A& K4 S6 M
bool m_bAsyncFindRunning;
* H) O6 ^! |+ H0 l- R HMODULE m_hADVAPI32_DLL;; v5 D9 ]% Q% }: _4 Z
HMODULE m_hIPHLPAPI_DLL;
1 |' }/ R3 J( ^0 t bool m_bSecondTry;
2 Q: z6 i1 [$ A- S3 h! e* c bool m_bServiceStartedByEmule;
/ q1 k- d5 y0 {) t bool m_bDisableWANIPSetup;
/ g! b, @3 S1 x bool m_bDisableWANPPPSetup;
6 |- r) l5 W( h _$ L0 a' o# e; g" M1 a2 J5 _6 g; v9 N
; g: a3 Y( i3 n
};8 S7 V6 L0 W3 _9 w2 y6 s
& l1 q, H0 x, [% F/ i# H+ W0 j# U
// DeviceFinder Callback
: k& d$ S0 ]5 n6 L+ H7 \& [& u. D$ v/ rclass CDeviceFinderCallback
) Z0 N; e1 _, K, V8 }4 J3 z9 `( k7 S : public IUPnPDeviceFinderCallback) X% ^6 F' Y9 I ` T2 B
{) {6 v+ x& l1 t" R
public: m, e, p' Q% @2 B5 T& w& W
CDeviceFinderCallback(CUPnPImplWinServ& instance)
( S) D* p" o0 l : m_instance( instance )
9 V# ?4 k1 c3 R W8 D { m_lRefCount = 0; }
; t* a0 X& X0 A6 W% F$ Z. K2 ~1 n' P
) {* P$ Z1 p M7 A W* t* j/ t STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
8 e2 i; r* I" Z! p STDMETHODIMP_(ULONG) AddRef();: [% c; v) j* P1 V' z5 f; ^. p
STDMETHODIMP_(ULONG) Release();
0 p2 |( H- R6 ~- P9 H6 G; m! `0 L Y8 l, X
, J- y% P: F: f, D$ I. d9 Z% G// implementation
7 C: U* T1 E7 T7 R) Tprivate:! m/ O; t. h( g7 e: x2 G
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
4 i' L, C% Q0 f, m HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
8 q% M/ b! ~0 p: f* J7 D: v HRESULT __stdcall SearchComplete(LONG nFindData);% [3 o. a5 C1 s W% R
6 q# B+ Z8 e! q$ F
2 T: W; Z/ K/ S' a! R% ~ wprivate:
7 L) A: J7 T1 w* ]) S CUPnPImplWinServ& m_instance;
: l, v y) k/ z LONG m_lRefCount;
; E. l+ P: \6 _' M# \% o: x o* h};
2 {$ D0 `4 H: u' f7 f
$ f7 o+ w2 S1 s3 g* o
6 C5 [2 J$ J1 ]+ m( p3 Z5 q// Service Callback 3 _/ B+ b7 b0 t: F' Q/ l# R) |; E
class CServiceCallback
% N( c. y- j8 K) P) M3 } : public IUPnPServiceCallback4 v+ K0 ^7 A9 I2 V2 W3 S- W) _' h
{
/ @# J* F% P, I! b6 s8 l) c5 z) [) _public:% \8 e4 a- a8 S" c
CServiceCallback(CUPnPImplWinServ& instance)
# o6 H( c9 V/ A- T : m_instance( instance )
2 g: |9 _2 Y, e1 n h { m_lRefCount = 0; }! j1 z6 A# q# I# Q8 ?$ ~% _9 S
7 M# X1 ?' ^1 s STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);# B6 H* q5 h8 v3 M# t
STDMETHODIMP_(ULONG) AddRef();
& G, |3 E/ |. H9 r; f3 I5 c STDMETHODIMP_(ULONG) Release();
; q6 W+ W$ ^% Y7 u* ~- n, ^0 L
8 ]3 J2 h: K$ c9 w% [' M5 @8 o, C6 R5 u5 l" O+ }$ G2 g' Z
// implementation
, K" [& w& o3 v: y0 gprivate:
" e0 ~+ M6 x- h" |$ X HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);7 d2 W7 ?* U6 W
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
: w/ s. [7 M3 I8 j
+ K) K, A* A U {! t4 S( G% j# d" {0 v! ]# A( V
private:
& o/ s0 @/ n; ]* G8 f1 e/ n CUPnPImplWinServ& m_instance;4 c' p+ w4 t! }2 D
LONG m_lRefCount;
. s: G0 K: O, k- g3 l; j" O6 S};
! u+ r& K/ ]( n; u+ P9 f- X: R
+ Z$ S. I/ ?- h
6 A) q- J. m& c! \: p/////////////////////////////////////////////////: I/ V. p1 C3 [ _
' l( B, o+ a$ z' l7 G- d
8 Y4 M& j7 d; O H
使用时只需要使用抽象类的接口。
+ O* B; G) Z, Z4 t9 C% dCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
7 L' R2 S8 c& A' b; aCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.; o3 y$ ^ L* C: }3 @, S* A0 \
CUPnPImpl::StopAsyncFind停止设备查找.
/ i# Q% D" v2 e# E. RCUPnPImpl::DeletePorts删除端口映射. |
|