|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,) b# \$ H& i* x& J- f
& [- ]- U" ^$ W8 y, i
& [ n2 M8 I2 }2 e7 q7 l' ?///////////////////////////////////////////
' i* v; h @! B2 R7 v# H+ }% N//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
% b$ z% U7 W! K& C/ ^
. u: J: d; V: j& R0 Q
4 h7 s2 z& e% P! _# v! o% E1 m ?" q& M#pragma once
( L9 e9 x; \# j#include <exception>* o* D& Z1 w3 r
( d( Q9 G) g9 C# T& s
3 d: s, s" `% ~. {" z
enum TRISTATE{( U f8 ` N, k6 S4 u& H
TRIS_FALSE,
/ s: V% Z% Z7 g+ n5 u7 t TRIS_UNKNOWN,8 S! k5 v) w1 m8 q ^
TRIS_TRUE4 Z4 o0 ?& m# v& t( h& p& ]
};" O7 ~8 _5 q0 N! b: N5 `. h7 A
( ^3 E8 Y# d& Z: a0 _ p
2 K5 y* T" S& E* a
enum UPNP_IMPLEMENTATION{: {: _; h9 w3 }# r; h! s+ u
UPNP_IMPL_WINDOWSERVICE = 0,; V9 p" B2 r& Q8 o
UPNP_IMPL_MINIUPNPLIB,6 O. A; j1 L. Z& x& Q6 S5 T: z! Y
UPNP_IMPL_NONE /*last*/
6 O5 w. U8 I/ d/ v: v};5 e% S3 }! J& S
% [9 U" T# }0 h7 N: @9 K
! O% ]& F. F! ?* L4 t: l$ B, v0 A
; l \ r0 k9 R! U
+ D( i7 g" e& \ @9 w+ Hclass CUPnPImpl+ w( W/ s x+ f% H; o
{9 Z, ~( s2 V2 ]
public:0 I l- O: r7 e4 l1 p
CUPnPImpl();5 ]" S+ G g2 B( Y' ~
virtual ~CUPnPImpl();
5 @( Z5 n3 X- e6 c* d: ?$ K( c struct UPnPError : std::exception {};; Y+ v0 Z1 {) z, `9 f* f# r. s6 f
enum {
' w" d1 F* U& ]5 `1 } UPNP_OK,
8 O$ x i0 p8 I& q% J" n UPNP_FAILED,
+ P, o% p6 `8 ~' S7 w: f- L4 p UPNP_TIMEOUT
; |* ~) f4 K d2 H };
, @) g6 |& [1 p9 d$ e- k6 r( w4 ]
. a3 W; N9 x; Q: L2 |7 e& P virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
8 P( M/ o# H) V# \& z virtual bool CheckAndRefresh() = 0;
& x( A5 M( b; l) |- a' L+ V# p) m virtual void StopAsyncFind() = 0;7 w. J; {3 a- {0 I7 f' e
virtual void DeletePorts() = 0;2 ?/ |: J/ A1 G) l, j d
virtual bool IsReady() = 0;
6 {: m& [5 V/ v, X' ^ virtual int GetImplementationID() = 0;
" w8 g5 L7 r# P# D* w
: }! S/ Q& j0 v* {, s4 R void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
' ~/ f2 Z: r7 U1 f- D4 K/ _5 x2 o+ ?. O% Y5 _- B
% w6 U% K) v% w9 Z void SetMessageOnResult(HWND hWindow, UINT nMessageID);/ L ?* H$ q* x: I1 P& S# t3 r5 P
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }4 }) [1 U8 w/ K2 \# e1 T
uint16 GetUsedTCPPort() { return m_nTCPPort; }
7 t7 m. B& W3 f: D4 Q5 [7 R# L uint16 GetUsedUDPPort() { return m_nUDPPort; } 6 D, x% B8 S7 @1 S
, ?1 Y& g) B% w+ f; A
$ I6 z( |9 O( p6 o7 ?2 `2 [// Implementation9 N3 I3 R/ w6 n; A5 j# s. z
protected:
( z( x& L2 j$ D& j( z" j" |9 y4 v9 b& g volatile TRISTATE m_bUPnPPortsForwarded;6 h; G+ T& Y1 x" H7 N
void SendResultMessage();: B. s) K% _" V, x
uint16 m_nUDPPort;
" O2 k" C7 p8 O9 k8 z; l6 p q uint16 m_nTCPPort;
8 {* X! _2 r0 { `' y7 q! G2 ? uint16 m_nTCPWebPort;
: i7 u, v' | v: h/ c. y bool m_bCheckAndRefresh;
}% h% t+ Y8 s4 R- Z6 N( {, S& w, z
% p9 ?& C* w. @ b% Pprivate:
8 v- T; y5 E" F4 ]1 I HWND m_hResultMessageWindow;
' k: E4 l9 I4 b4 [/ l( g UINT m_nResultMessageID;7 g D1 k& J0 I& K! U; [
) [$ Y* l# ^( k/ F: G+ G, V( T7 e N4 y3 g
};
) D1 [) Z9 p! x1 [# d
3 S }/ p6 w$ a6 H" S9 s6 G4 G( T6 f/ r$ @3 r# Z/ g, R
// Dummy Implementation to be used when no other implementation is available) c8 v& W3 A, ^' e! J: W
class CUPnPImplNone: public CUPnPImpl* w( J5 r" \7 V G
{
- _) b* {/ l/ z' l% l/ Ypublic:
9 Q) g4 R/ e- C' ^5 q4 B virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }2 I5 ^8 B4 b0 G& ?& Z
virtual bool CheckAndRefresh() { return false; }8 [' f8 s6 Q1 |1 g( f- r
virtual void StopAsyncFind() { }
+ F# V2 _5 s( Z/ s( m virtual void DeletePorts() { }, w0 X) q% h4 H0 F! ]
virtual bool IsReady() { return false; }2 O1 `9 f4 H9 e7 d
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
/ f8 D* b: `6 O: D};
4 ]. ?) i* w3 T* b& \, a
5 d* u2 }; c# }& n
$ d+ T1 I3 o8 `3 n; p( o+ p- s/////////////////////////////////////9 I3 x- n" B) e/ [
//下面是使用windows操作系统自带的UPNP功能的子类
& ^8 Y9 l0 D' N6 \8 i J. F: p( k4 j% l3 n
; Z1 X# V ^! _, g4 N5 _" n! v+ t& k3 ^#pragma once, |" i/ o9 E1 e+ W' L
#pragma warning( disable: 4355 )
( Q. B6 B8 Y# y2 z- y
' C$ z( i! W. z3 |" L- X5 D$ L% o0 j7 U5 b( e
#include "UPnPImpl.h"
# M, X( b. {, I/ j9 z#include <upnp.h>
( l2 d6 T6 z( S5 l3 B7 w#include <iphlpapi.h>
9 j+ `! a2 s5 R#include <comdef.h># Z8 c/ K" S3 e# Z! N# H! |
#include <winsvc.h>0 H& u( F$ j% j% A" u5 z
1 j( A5 j; e! ~
8 B& F5 v) p+ z* o$ I# q#include <vector>$ s) n m' g; C, G( Q. _! i# ] @
#include <exception>& u3 [0 O2 Z( W1 x0 W
#include <functional>6 C" s f/ L- s4 D) l
- p" e3 e# P+ e# _0 [$ N
: S1 f/ h5 X+ |$ `2 _7 K$ I- [$ X2 x
% U5 R* f( ?1 u \& a! ytypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
$ ]2 f2 ?) ]# e. k! |# D( M/ G5 itypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;) ~; S6 Z& w3 ^
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
/ I& z: z: E3 U0 m c2 ~( ptypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
8 Y9 G* I0 a1 e8 J0 rtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;! N( \6 ~& r* a% |
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;: q$ q' T& A8 a4 _. _; l- v& T
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
7 K2 n% L1 ~4 B3 Y5 b/ l* @4 l: ^9 Z* V
) b+ I: Z! T9 |! @0 o& e0 u
typedef DWORD (WINAPI* TGetBestInterface) (, h* _% w1 Z( \
IPAddr dwDestAddr,0 L3 K- [% V7 U' t# p0 a
PDWORD pdwBestIfIndex" i" Q, g0 [6 l5 j+ M; a
);
3 M; l3 R; Y/ }. s' M% ?5 G
- |8 `( Y# n- g
# X! `3 M' D% A$ Y5 Vtypedef DWORD (WINAPI* TGetIpAddrTable) (' G& e( l# E& @9 A; f
PMIB_IPADDRTABLE pIpAddrTable,
+ H. ~: }) M% j2 y8 v' _+ O0 i PULONG pdwSize,
* M" f. }( U: ]5 G4 U5 d7 G BOOL bOrder
% r5 t; t* o- l);
* s3 S/ B) G# S4 y. K. q
- I( Y7 O; h2 q2 ]* b. D: |) j6 u3 @- s$ ]6 _) {. D* n/ u
typedef DWORD (WINAPI* TGetIfEntry) (6 l2 B( y' c C3 O/ P
PMIB_IFROW pIfRow2 `, I, I8 j) _/ Y
);. j3 W. P5 k( w# Y, I
8 n: A9 b5 A6 m3 `( T2 |- w
/ k4 ^7 `' `) Z/ V5 @/ }# eCString translateUPnPResult(HRESULT hr);, n" G9 i2 N& G! j0 p6 e& u7 s* r
HRESULT UPnPMessage(HRESULT hr);9 p: L4 p* A' C# ^: v- U8 g
2 k; t9 _' T* o) r* L3 [& s1 ^
' }- Q$ c. }" b! fclass CUPnPImplWinServ: public CUPnPImpl# s4 i4 ~: l8 h0 x
{
6 W1 O( f, ^( z* `( x0 u" A8 A1 o friend class CDeviceFinderCallback;- }5 ]# Q& l# J/ @$ ^ D
friend class CServiceCallback;
& \" v9 I+ r' b. f9 u% w// Construction/ r! C% |$ J) p: G, C' U) G
public:
. M! o# L3 B: _. |! D1 P! `- e7 B1 m' | virtual ~CUPnPImplWinServ();+ d6 n2 C6 {' O0 B- v
CUPnPImplWinServ();: [& s0 _: T& @6 a$ b* h
k- w7 p4 b3 J' \3 s* N1 g; x4 p3 @$ W& Z* H) @: l4 u
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
# v$ s! ]/ l5 N# ?+ @* K virtual void StopAsyncFind();/ C8 _; Y( f/ {1 l2 K/ ?
virtual void DeletePorts();0 F" q7 U: {8 k! S* b+ p/ [4 ]
virtual bool IsReady();( o2 p/ a' H- c% I5 F! r
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
1 l9 ~0 B# C& q) W# A! [0 E6 J% i/ A( m! _9 W4 x
3 j& o7 K# {$ @- x. k3 \1 f" s // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
6 C- I& V0 u- A% R' `( p // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
7 f" p g8 ]( X1 o9 `" h1 J. r5 D virtual bool CheckAndRefresh() { return false; };' r9 G. P2 z! R
2 j" p V: ]6 h& d, s4 Q% a
' H8 l* Q# h% b j# I' a" o+ o" b1 nprotected:4 Z3 J g/ ^/ H: W. O1 m Q( ^
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
% T V1 F8 V _ void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);* f5 `( A$ v/ I+ H
void RemoveDevice(CComBSTR bsUDN);, g( r( c& x% [
bool OnSearchComplete(); |# c8 d& g% c. ~' k
void Init();7 l' T) j5 ]5 B$ o) I% w
; g$ \) H* a9 j& l
1 J* L- Z |5 b- k) }& c+ n inline bool IsAsyncFindRunning() 6 H7 ?9 M/ }& J: r/ @/ z
{/ a* s9 o* E. `0 S" ^ J% C6 X
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
0 n4 F) l; S( ~7 B {4 V, v" E5 ^% N8 M
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
& G0 A% J4 z4 a1 e( L m_bAsyncFindRunning = false;
6 X5 O' O8 N% {. K }
8 m1 O0 I% o3 s" A MSG msg;
2 h l( `6 S$ o2 y, U, |! \4 M while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
, ^* Y$ i; _ _; X& d {
" B. X+ ^$ e6 p1 K TranslateMessage( &msg );% Y. ?9 C) Q: N# X
DispatchMessage( &msg );+ `5 v' I; J$ K' N. T5 N
} j, a2 n7 L. j/ P& E" b+ S/ t
return m_bAsyncFindRunning;
; H/ M* L7 M* B5 j }
- w. ~% f- J& I( ]$ B8 l3 q( l* H$ `5 P" G" O" [
0 B5 C- f" w" k/ @5 a R$ a( e TRISTATE m_bUPnPDeviceConnected;
# q; {3 d1 E& b* _! ?7 w2 U2 i2 B0 u3 g% j
9 d- y9 g9 {( T2 j- n
// Implementation% J- }3 q1 b1 b. I! J# S+ G% F
// API functions+ p2 p8 H; t- D6 _; t( C/ C
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
- } I2 \, A/ F' [8 X: f- Y SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);- E+ A8 b( N* L* q$ O: n9 Y m
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
* {& d- v( v; t1 I( G) [ BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
5 ~% P+ n+ P, D) i1 { BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);$ m$ E6 |" R, R8 J
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);* l% S8 M7 ]. w9 W
) e: ^, z [! S4 U1 e/ I
7 S/ o' n$ V3 |" H3 Y% s2 A7 s* [' C
TGetBestInterface m_pfGetBestInterface;& G) D Z! E$ a" q# Z- Z) m$ r
TGetIpAddrTable m_pfGetIpAddrTable;/ P: M7 H" \; A m0 j) u" u1 y3 ~
TGetIfEntry m_pfGetIfEntry;# H& R9 j z6 w, b0 ?+ ]0 G- Z9 E
4 _7 [! j% ~8 G: A" f+ I V
( {- u/ [. h2 ]$ r static FinderPointer CreateFinderInstance();
8 T2 Z) c1 {. v' G$ I% M9 d8 Y, S, t struct FindDevice : std::unary_function< DevicePointer, bool >
5 n6 F! d5 z! a1 B- v {$ \+ J9 J, ?- o d3 M. Z9 w
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}* _" K- v1 |5 [9 v- Q7 q( @2 s
result_type operator()(argument_type device) const* w, P$ w- f: `3 l" c
{+ m1 \4 _) |, C# a! g8 Y
CComBSTR deviceName;" Z& k2 N2 d; F4 m( Q
HRESULT hr = device->get_UniqueDeviceName( &deviceName );7 x9 b. j( x' Z2 Y* ]7 l
4 U6 s" c) f- Y4 X1 t/ c. ?* z% s
% _1 l+ T0 U! a/ a) o2 { if ( FAILED( hr ) )9 y. Y) X9 P0 O& j; S" s. f/ e
return UPnPMessage( hr ), false;# ] v: |3 I: A2 ~1 K* e( M$ s% M
4 l; ~* Z1 d0 p' d
+ |8 K+ w4 B: n& M3 m% ^/ P( T3 g return wcscmp( deviceName.m_str, m_udn ) == 0;7 h, v6 s5 p( G" Q* l
}$ w- E9 v4 Y; W3 K, g& `! o
CComBSTR m_udn;2 [/ D/ V; t- [+ r) S! c
};$ [+ U; Y' t1 b1 C( }
+ ~; z, A7 k" H( @ [
void ProcessAsyncFind(CComBSTR bsSearchType);! N$ B" M4 P) x$ c' \
HRESULT GetDeviceServices(DevicePointer pDevice);/ ~8 z: l4 d; h6 l: w
void StartPortMapping();
T z. }$ L1 y& \$ i6 @3 ? HRESULT MapPort(const ServicePointer& service);
5 ]# K, n Q6 S1 {2 F: ] void DeleteExistingPortMappings(ServicePointer pService);
% b& V4 ^( k6 _1 k void CreatePortMappings(ServicePointer pService);) H8 {8 O: }/ f S5 Q x" J# W7 I
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);9 _0 L0 `; _1 G! P
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
( g- f6 w8 i/ B9 Y LPCTSTR pszInArgString, CString& strResult);
( x) k5 ]$ U- P/ c) F void StopUPnPService();
1 r# b; w. q. q1 ]
$ j# p2 ~3 {6 b, D/ v2 z/ N1 U0 W/ K9 S! N/ M% e% e
// Utility functions' Z! A$ P& j0 c Z
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa); F0 e1 u$ |# Q- H7 K' T/ b
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
4 X! O# Y) h2 M INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
8 ?9 j1 D0 I; y9 @' ]+ ^ void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
0 o+ L, b6 ]2 Z4 R/ |3 u4 J! H HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);6 q) R0 z+ @( H3 f- }% O* D
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
! N8 I1 S, V. F7 E CString GetLocalRoutableIP(ServicePointer pService);
, M/ O, P& Y8 J
( H$ a0 C5 ~: [2 K7 d
4 @- g; T# R6 X E// Private members
) `7 ] @& w# z+ o0 mprivate:- `, s2 }3 t4 K3 \. B/ l, m/ t
DWORD m_tLastEvent; // When the last event was received?
7 B5 @5 z# c$ T6 ~8 z' K$ \ std::vector< DevicePointer > m_pDevices;
: C% v' G \7 ~8 l0 U std::vector< ServicePointer > m_pServices;$ u; ]" y! {. @
FinderPointer m_pDeviceFinder;0 w4 R) u* ?- C6 h! I1 p" X' h$ J
DeviceFinderCallback m_pDeviceFinderCallback;8 h: o+ `8 ?: N- [* T
ServiceCallback m_pServiceCallback;6 C' Z; z1 n, p6 I
) I f: B, D4 B, z! c0 k! S2 n
, P- Z4 Q( \% N) L LONG m_nAsyncFindHandle;
3 G, J& A% Z5 `2 D2 H bool m_bCOM;% a! y% {" V' @4 V% | f
bool m_bPortIsFree;
4 q# _7 V5 O# X CString m_sLocalIP;
: {( r- A/ _; }* S: G7 G- L" l CString m_sExternalIP;3 S/ ?2 u' G7 @9 w" W1 c3 r' \
bool m_bADSL; // Is the device ADSL?* P" p) T9 J5 x9 C8 Z
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?' s X1 @' F- [' _( K! v/ q5 ?9 |
bool m_bInited;
- V! ^* r0 \% O3 S2 m bool m_bAsyncFindRunning;
8 I0 ], q/ U+ X1 Q8 M! {4 w HMODULE m_hADVAPI32_DLL;
6 a6 R+ d+ O' l0 z8 W HMODULE m_hIPHLPAPI_DLL;
3 c& I4 F0 o4 A# y+ R% N3 `3 n bool m_bSecondTry;
( n) j) V, _4 Y/ b bool m_bServiceStartedByEmule;) E, Z& n; j' X! v
bool m_bDisableWANIPSetup;
9 I/ p/ g) p K6 t/ l0 b1 ? bool m_bDisableWANPPPSetup;
+ J7 u; y/ ^" T1 {7 \( R& j# Z8 z; D* h( v+ r- f
9 }- E! k* O6 W/ c1 u2 n
};
4 |$ ^1 R& [3 |0 r8 n- h& ~
+ q W$ b1 x* a9 B. K/ Y
3 S4 O+ ~& H$ p4 e2 w// DeviceFinder Callback4 g I Q+ ^; ]4 ^% L2 G
class CDeviceFinderCallback
5 K, l+ V1 @7 D8 L4 V1 ~ : public IUPnPDeviceFinderCallback
# T# g9 V. y- v& y{, i1 A/ ?9 u2 ?% A) z% z
public:
/ |9 S0 j x0 ^; t" t- c9 |1 d, m CDeviceFinderCallback(CUPnPImplWinServ& instance): b) b! C- ?/ C. ^4 Q; S H
: m_instance( instance )
, T2 b1 D* l, q$ r6 {! H- I { m_lRefCount = 0; }% L, z2 R3 M. [- [" Z9 D
) \( o C1 f. X! d- l/ S; T2 s' [" S/ n+ h8 S$ p+ G) j, \
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
+ o8 C- z0 y( H. H STDMETHODIMP_(ULONG) AddRef();
* ^" X- p& M$ c1 S1 R( \ STDMETHODIMP_(ULONG) Release();" R% W$ S( P( D; t& M
1 J( ^2 p$ G4 B5 N, { A* D6 [" U7 X) a$ o1 Q
// implementation5 O! F) A$ }# q/ E
private:
( R" [( e" B- \, t0 y% L6 o$ X8 L HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
7 }1 i* |' G2 n& U& y- G9 g" o HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
' j; W5 \) B" U HRESULT __stdcall SearchComplete(LONG nFindData);
% z: k* O+ ]1 }! q8 `" R: }2 n
. Z# ~6 ?* V/ T5 P7 S/ E4 y% ^# n# m1 h
private:
: U3 Z( {/ r- \ n5 L: j& I- b CUPnPImplWinServ& m_instance;
6 O7 l! s: p( ~# H" e' K LONG m_lRefCount;
5 b$ o; L! `* x1 D, h4 d};
1 o% o( A, Z# G# I4 ^3 D0 d- }' z
! ]0 N' d8 E9 j+ s- f) o6 e5 f4 ] O0 q. B
// Service Callback " ^' y- V% h9 b- y9 b
class CServiceCallback
- j) y7 q6 i: B3 D : public IUPnPServiceCallback
9 U0 D" Q1 W, [6 }$ g; R{6 S! B: @- t% w1 L# k) R
public:" S* I1 {: I; G5 Z) n
CServiceCallback(CUPnPImplWinServ& instance)
+ |; I- }4 n f; H Y. A : m_instance( instance )
7 K. b/ f4 Z" F" H { m_lRefCount = 0; }
/ k9 X" A9 ]4 Z1 s! Y. s- W+ i 6 _/ r6 j! j6 y: H
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);( i% @. H+ \# L! P7 E. `0 B
STDMETHODIMP_(ULONG) AddRef();( x1 i9 c V" j0 c
STDMETHODIMP_(ULONG) Release();
) E, ?8 E4 X; @4 [* d5 R2 P* B* P% F+ i- J4 N: A
+ M$ h2 K s+ L( S5 O) l
// implementation+ }6 l1 k4 n/ n; ^ `, W- [$ E v7 o
private:6 P# v4 F2 E x
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);% H/ E/ i/ B1 x% J+ ]8 |
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
2 G9 U! k& O ~( O2 K+ O# p) c+ g, Z$ q+ _: M- e. y
1 d( t, L o5 F! [" n' Kprivate:
# m/ y) Y/ G0 J8 e5 I CUPnPImplWinServ& m_instance;! L& y1 x, [* @: u; Z" Q. q. g
LONG m_lRefCount;& }5 M& I4 q0 p0 H1 B
};
7 D; r! O0 }' U# H M) A. ?' ^, b/ w4 m
) S" Z( I# F- ~& N F' A% `* t& C8 w4 j. R+ n0 L( [; Q
/////////////////////////////////////////////////
: s( m: t. F s7 S# _% ]4 l) `0 N! `$ @/ A% C8 A# L- ^5 d4 S7 Q. }: }8 W
# @9 B1 I' X# F& i$ ^2 ?使用时只需要使用抽象类的接口。
' z2 O* p# [ B9 [CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.; B+ g+ S' L, ^! ^. d5 j- C
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
- C8 U9 C' `1 d' g5 I4 ]4 XCUPnPImpl::StopAsyncFind停止设备查找.
0 E0 E; G8 t; b+ O* N* v YCUPnPImpl::DeletePorts删除端口映射. |
|