|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
" Y- @) n' F$ X5 A0 [' \' D5 ~- Q2 u- U2 Z! o3 q
( Y; N- \8 m1 r///////////////////////////////////////////2 @& h0 O5 {, n- L
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.- X6 c0 O+ z' e& U. i
/ d, E+ ~% Q/ e9 C$ E+ h; j
5 q, n& u; n6 R% F5 i
#pragma once
% L( H# u. t9 F; i1 i#include <exception>
, j9 t& o$ ]8 ?& X
! z) x" F, N9 Z5 [; A; l9 X6 f" R
0 ^2 W$ V6 q" {1 R4 A enum TRISTATE{8 ~: |- r: w9 e/ Y9 R" P! z G
TRIS_FALSE,
. h, C, A8 a/ f0 Q+ s TRIS_UNKNOWN,
, V8 `. y5 d0 u. R, D+ { TRIS_TRUE! W( A) u. ]% X: u3 U0 V; ~6 l% @! X
};
9 e! x0 E. W+ u" L z: S
2 r1 P2 H. y5 a: {* q H* f
8 ]% a: B$ i8 [7 x% Uenum UPNP_IMPLEMENTATION{; i& r' V1 K4 a8 `8 _
UPNP_IMPL_WINDOWSERVICE = 0,
4 j8 E9 @* l C. k1 K: _* c6 X& j UPNP_IMPL_MINIUPNPLIB,, ?' w+ S8 e' C" I
UPNP_IMPL_NONE /*last*/: p9 r w' c: _
};4 C; b% s7 l/ b* g9 r& q
4 F& t5 t. ^2 V- m& s
7 R9 ?( T+ S* Z9 w* ~6 U
! B# E* }; O, [% K/ p% `
! z! v/ p! @. u5 R
class CUPnPImpl
+ C2 s# |% n7 r7 O6 j. t{) @, K( Q; {' \- G) m
public:
, {! _9 D2 r. W: f2 P CUPnPImpl();
3 y9 c" A( z0 j4 j virtual ~CUPnPImpl();, D) K0 d( q5 b8 P( G: m f6 k
struct UPnPError : std::exception {};6 l$ c* Z- ]% {- ~8 a
enum {
- s5 ^: f* ~7 n2 o, D6 Y: D3 R UPNP_OK,
1 P0 q) T! Y2 O* d9 M2 \* Y UPNP_FAILED,) Z; d" p3 ?: D8 M$ i8 u: {9 c
UPNP_TIMEOUT
7 N! ^7 T9 ~) R: F& _5 N };
0 @0 u& N" Y$ J- |- ^9 l) c7 C$ r t' T' Q3 z: ~- k
- [9 [+ c( X3 J( L$ D! M+ H virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
: O) c1 U) ^+ f8 ] virtual bool CheckAndRefresh() = 0;2 k7 |% b, Z( A. D" b8 p- o' ?
virtual void StopAsyncFind() = 0;" J" I! o, w$ I% y( J
virtual void DeletePorts() = 0;! x7 f& s. J" U6 B
virtual bool IsReady() = 0;
. c4 Q! ?% V7 Z* V$ |2 @! y/ M9 B virtual int GetImplementationID() = 0;
4 a9 u' y- B$ K3 @
3 G. f" f, I' _ void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping) l/ ~2 P3 R+ l$ b4 ?; ]
2 X9 A& c, ^. ~6 T Y) D J
) z/ s( D/ s# l0 o2 c
void SetMessageOnResult(HWND hWindow, UINT nMessageID);2 A5 m- c8 n3 W) T. e4 d1 M
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }& B# C% F8 G3 u
uint16 GetUsedTCPPort() { return m_nTCPPort; }9 C0 b. c: {# o
uint16 GetUsedUDPPort() { return m_nUDPPort; }
# H5 o1 l0 F/ m. j( w" k/ g- E: R
$ y) k5 O* P, J( c' X" f# U
// Implementation- v# y9 b! o; I8 \4 i
protected:# ^' ~6 {" f; W9 ^
volatile TRISTATE m_bUPnPPortsForwarded;
7 d$ K M4 [' L* v/ _ void SendResultMessage();
7 G: A/ H! X$ k uint16 m_nUDPPort;
1 o7 E+ Z/ a; Y0 f! Z, `* B' T) X uint16 m_nTCPPort;9 E3 u! H+ @ L; {
uint16 m_nTCPWebPort;- j9 U, j5 V! Y# R) r, r5 Z
bool m_bCheckAndRefresh;
/ w$ D, C2 {! g
" k5 ~( y. d1 c' o6 G) e9 I; }
$ u& u7 `' a# j. b6 Y) c4 ?private:
& L! U! u! m' T1 r! d! r( v& a HWND m_hResultMessageWindow;) e( c' b8 ^5 u u& F$ ?3 ]" R
UINT m_nResultMessageID;
4 K. O. k% [' f3 ]% c% O) V. Z
; d* h( f& a( y5 E$ L8 n T
/ f$ x; H ~7 N, ~6 h6 W};. c6 _/ A; Q" o/ s5 p1 T/ A
% H* Y7 P( Z) z: `4 d* t
( U/ l7 u( I. h5 d4 v4 A
// Dummy Implementation to be used when no other implementation is available
* o) m' o! }+ O: P+ Dclass CUPnPImplNone: public CUPnPImpl
- A) r# `( b+ H' y9 q; N3 n{2 t4 ], V6 V3 a2 s4 \
public:
$ O& K# E' [ ^) R; M2 a virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
. Z4 W+ b! {# U9 h7 L+ g5 s virtual bool CheckAndRefresh() { return false; }
: ?4 r% [: A( {" U$ b6 L t& V virtual void StopAsyncFind() { }% G! j) A$ o9 \4 o$ L% e
virtual void DeletePorts() { }
' A& z) g; D/ V: u. B. R virtual bool IsReady() { return false; }2 E: a; y5 F5 c# J
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }5 R: @& U0 P `/ {( ~
};
9 D0 K/ z' @/ H4 X4 b+ b3 a- _! o+ n) U, B7 U
" x T7 k9 {7 B% q( h
/////////////////////////////////////
. h& B. R T: H! q0 [//下面是使用windows操作系统自带的UPNP功能的子类- [2 u6 [' U9 J ?; e9 y5 Q
: A) c1 K* ^5 d U: y
5 C$ k5 u& ?: o8 M
#pragma once
% K2 n: t' m U- K: Z4 [7 }#pragma warning( disable: 4355 )- W* Y4 Z, z$ @( W3 [- N' w H1 o7 c
8 y, d6 c9 K( Y8 }/ W5 \7 d& Y( [/ c5 H# f, A! c4 T% K
#include "UPnPImpl.h"
$ ^7 x* i6 U/ B+ ~#include <upnp.h>
. K) \% J. }; ?! y& \#include <iphlpapi.h>9 A0 _, q/ q% Y; [+ L/ a3 @4 ]
#include <comdef.h>
0 q2 X5 A' \% z' j9 h2 R$ j#include <winsvc.h>
; U. t- }. J" h8 z! R) ^& F/ ~- l: X/ T5 v2 P) A! F' T s4 L
+ c0 F# w% q! P2 p#include <vector>+ [2 r+ l! L. V4 z( l7 _
#include <exception>
1 B; l1 ^: N* X& i% k; F#include <functional>
2 n: m& O9 y; T3 ^" R4 W" \4 X; A' I6 \
/ h1 ?8 O, F& K! M1 S% K* m
P$ b3 J" x i6 M3 v4 G# s* C& F' [
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;/ i/ F* h2 t" z: o( I/ j
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;0 m c+ @) z4 B9 J1 G
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;; @7 `$ } n, \
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;6 X+ f3 S4 d" N% \% K
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;6 I) ?, W5 |+ f; }; |( a: @0 D6 P/ t' ?
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;; R1 q, }$ W% } j& X
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;4 [/ p3 v7 Y9 ?6 @
& F/ U* x$ r$ z- {, C% T0 p- o$ y6 B: i% u. C
typedef DWORD (WINAPI* TGetBestInterface) () C0 X2 K$ c' W7 h; Y3 j
IPAddr dwDestAddr,
5 y. {/ O9 ^! [1 m- O PDWORD pdwBestIfIndex
7 [8 I7 U" ~1 O);
. `1 L+ S5 e. ^/ V8 v- k: m4 V4 d5 o& A( G0 V0 {, d
' T+ {; y0 n( G, V
typedef DWORD (WINAPI* TGetIpAddrTable) (
: q7 Q+ @$ F2 k8 |5 H9 l PMIB_IPADDRTABLE pIpAddrTable,$ u# _& t/ E4 i% N) e/ T( z
PULONG pdwSize,- E; U; L$ Z; d3 V; n# {
BOOL bOrder" b& V& L1 k% O# {% _9 G& i1 i
);
0 f: B& e/ m; \7 N t2 g
8 S) A) n; C% T+ n% s: c5 ]! R
2 |' I9 W# U$ c. I; x9 z) ^typedef DWORD (WINAPI* TGetIfEntry) (0 ]; C- T! Q( L& u. K% Y Q3 y* A7 p
PMIB_IFROW pIfRow
* _0 J1 Y: P( ~( n);
6 @7 S3 D) e' k& ]
( B8 A' ]1 i* t, k0 N
' u3 w: m# D( ?* R( y& zCString translateUPnPResult(HRESULT hr);
' P5 V* n8 \0 l; y! QHRESULT UPnPMessage(HRESULT hr);- u. ]/ j/ {8 I$ I. B* D/ L
! O- v) Z' R9 d1 U! u% d2 r& p$ V0 c5 |6 h1 G2 F3 C# M
class CUPnPImplWinServ: public CUPnPImpl
' N9 m1 [' n, @) s/ I$ |{
# b0 |8 `8 d6 o" N! e9 [. ~2 _ friend class CDeviceFinderCallback;& U, F" n, Q" {; W& x
friend class CServiceCallback;- M, C, o- T, a) R/ \' K; F8 J
// Construction6 p, n f& |8 u3 `- n+ f
public:
' l8 t9 K) ]( G j# X6 F virtual ~CUPnPImplWinServ();
& Y: j9 `& G; X! D: J9 R CUPnPImplWinServ();: w7 I q/ E: Q" I7 f
6 m& ] e- C4 Y T
1 n+ X" f0 a2 A. |, M6 @ virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
- Q+ y# H3 O# @+ V; Q0 b virtual void StopAsyncFind();; ]) V- y8 Z1 h1 H
virtual void DeletePorts();6 s% C: S, x4 o9 M" }& {
virtual bool IsReady();
" U! H3 [0 ~7 s/ z5 T, \ virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }6 Y, w* v3 A, Y( |8 [1 T% k
# g; E) `( o4 _- h3 Q
1 x5 `0 v# C- O2 M& [
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
6 u" ^: [3 b# N9 b) ?" f // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later, T) m1 B! F; D
virtual bool CheckAndRefresh() { return false; };
$ T4 z+ ?; `# J* [! c* Y' g) u, @. t' E; W- y% a
% p- f) w @6 _% h) P
protected:7 t$ M0 k; ^; h- F( I2 {
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);( _& O- p# m4 x& E$ E
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
7 A& [0 _5 S6 a+ ]" a2 ]( b- T void RemoveDevice(CComBSTR bsUDN);
. {3 m; \: q/ e" F, Y# Q* U bool OnSearchComplete();( u1 R. }0 u3 R, R, b
void Init();
5 {9 Q& d& \2 T" y4 M ?9 k* g& G' W1 Y! r! R. Q
# d5 V w8 x! i inline bool IsAsyncFindRunning()
2 T, S/ j) C( Z5 Q$ ?" Z( O {
2 G! R2 }& T* r$ N# b$ x if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )6 W& r4 Z) R& H5 p9 H3 T
{
6 [& Y5 G* m! m8 ?, u/ O; w( A. J8 x m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
- t: Y- L9 F7 `& j4 ^5 m0 r m_bAsyncFindRunning = false;
1 W! y, d' q% [' W, a, ^ }4 w% v. x Q2 q7 l& c D H- h
MSG msg;
+ {8 h) m& W; \# y while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
" i& `/ _, Y2 t5 u+ O. v( c0 M) p {
# n* Z4 w8 s; V' Z) N TranslateMessage( &msg );' ?. P7 A. o! x. |+ ?
DispatchMessage( &msg );5 c; Q& v% o9 q+ h/ D# Y8 ~
}
: \' X( V5 Y d9 _ return m_bAsyncFindRunning;( i* a% u+ G3 W$ q
}( l8 ?2 n; M9 s6 E% k# [5 y
- k3 d8 D+ ~! b6 }# {; w* @, u o9 I, e& G: ?0 u/ G4 G
TRISTATE m_bUPnPDeviceConnected;1 D3 m! g3 I7 N
, z6 h* J! O/ A
! O; N }4 z1 Z# R( D
// Implementation' ]- F* T S/ [5 A$ e* |) P! M
// API functions7 X( u& j' }: L/ C$ F5 M
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
! h7 O) y+ r2 N6 L8 v. S SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
# @( k! E' ^5 a6 j( p6 K* b BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);, L8 e: \3 o) e3 K' y$ J
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);+ Q w V6 C4 q+ E
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
$ y: y% I/ h, d7 F' Q BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
% E$ c, P1 ?, Q( o0 n9 ]
$ @, K. @2 q% S0 Y' u+ h e6 Q# R' ?4 g$ B
TGetBestInterface m_pfGetBestInterface;
$ C0 A* K) t# P6 C5 K TGetIpAddrTable m_pfGetIpAddrTable;
9 H( S3 _# Y( c; l$ T TGetIfEntry m_pfGetIfEntry;' _4 [6 b) E2 S( q3 p+ A: n1 K
% v' s+ z, Z" D2 q0 L6 ]- a
' l# l( G( A9 N0 t6 r static FinderPointer CreateFinderInstance();# L5 `1 F1 n. f+ r
struct FindDevice : std::unary_function< DevicePointer, bool >
: Y4 J8 b5 E3 c- s5 o$ e T% z- C {/ I' m& F0 L$ L' M; O5 x
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}; Y' S& B& O) N
result_type operator()(argument_type device) const' E; a# @3 n" O8 r
{9 _4 h$ [; t5 F5 G' u0 X# L
CComBSTR deviceName;3 `0 I- `- I! Q- G8 X. R. @" G# [
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
8 b" }* S6 t' I) H3 j
: D/ S9 [$ p v9 [
( L2 V" l% g9 k% ?1 p, v" R if ( FAILED( hr ) )9 `7 _1 \, a% E# z; I3 e
return UPnPMessage( hr ), false;$ H: `& W) e1 a y. d
- W `) y; z: U+ i
1 F9 V8 G* H5 f* w& C. R4 m( c6 ^ return wcscmp( deviceName.m_str, m_udn ) == 0;9 y# T& c; q1 K
}* `* ~$ M% `- e2 L
CComBSTR m_udn;
* f$ O0 ~& l" h! U }; r- Y: n6 E+ J" s' p) ?
/ p# t( b: J* z void ProcessAsyncFind(CComBSTR bsSearchType);9 F0 @- D+ i# v; f
HRESULT GetDeviceServices(DevicePointer pDevice);
, l4 S+ U8 G- g2 c, k: @; F+ b9 ^4 b* ]% a void StartPortMapping();& h6 x3 t, }* }
HRESULT MapPort(const ServicePointer& service);4 e( P/ G! Z% p x' ?7 F
void DeleteExistingPortMappings(ServicePointer pService);) l- C8 _( E4 P) r) m
void CreatePortMappings(ServicePointer pService);
1 f+ X1 |$ v9 y3 @2 k HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
) u, C- j, Y( P3 r0 U HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
% N# S( t6 N" W5 s1 T: q- E7 {5 d LPCTSTR pszInArgString, CString& strResult);
6 T2 C% O. ~- D4 s+ l" R void StopUPnPService();
; K1 T! _/ C5 c1 T* s, K) {+ z6 }, N& H8 Y( U# Z% w
6 p! P; x$ E' h
// Utility functions
3 v% L' g3 X3 {. r8 p; z* ^ HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);9 r, s/ |7 ~+ C* y# L
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);* W- z$ M6 j }7 i6 f; n) F) y/ q9 s
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
* X" z! n5 k. V) d' E9 j9 R void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);. e" Y9 {, x6 X2 w5 e
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);7 S* F4 K! Y" E
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);+ g! V0 C, `4 m5 N8 ?0 D& g& u
CString GetLocalRoutableIP(ServicePointer pService);- y6 |$ _/ _$ e, V& s$ {2 l
& l/ O( z" r4 G, W3 k
! N) I$ T: H6 C' A
// Private members
# y, _4 }+ q/ \+ H8 x1 S: }# dprivate:
6 }1 `0 Z; d$ N, \ DWORD m_tLastEvent; // When the last event was received?
$ ^+ e! h$ W1 x; B$ g std::vector< DevicePointer > m_pDevices;
" Z4 H- I5 Y8 e- Q' e2 V# u/ x std::vector< ServicePointer > m_pServices;
9 m9 e/ o- g0 s, G# z+ \ FinderPointer m_pDeviceFinder;
9 b" w4 j: Y5 X0 d& C2 i8 q) H DeviceFinderCallback m_pDeviceFinderCallback;; w5 y% J' J b- Y4 O
ServiceCallback m_pServiceCallback;
# W8 m; w$ u( O/ F# O
: H* u: v4 C6 A0 `* p" |6 t! s
: ~- g, B1 }) {& E9 P2 F( f( C LONG m_nAsyncFindHandle;" t) T7 c1 C/ @& h" D0 r. x
bool m_bCOM;' u) f# _+ y6 T
bool m_bPortIsFree;( q& F# T M. I, I! c- ]) K
CString m_sLocalIP;
; A0 O- q& B c0 t5 E/ w CString m_sExternalIP;
* V4 R1 p1 {8 E! g7 O( v bool m_bADSL; // Is the device ADSL?
9 W, O6 R+ \% u bool m_ADSLFailed; // Did port mapping failed for the ADSL device? n& h* R* W- p& z% _) |& V0 V* x
bool m_bInited;
: ?% f/ N6 g6 n. U; \4 I+ p bool m_bAsyncFindRunning;8 ~+ [$ f' h0 U G6 B w
HMODULE m_hADVAPI32_DLL;
( A3 N( k3 h* |6 _( S* o HMODULE m_hIPHLPAPI_DLL;
' F' N3 r2 I: Y2 n* t4 Q9 W5 |& o' c+ e, N bool m_bSecondTry;, h1 l ^4 O9 c' A
bool m_bServiceStartedByEmule;8 H/ w1 g2 n( g* T1 Y) W" t
bool m_bDisableWANIPSetup;
' }( s4 a& V" o# B& ]% o* ]3 f% G) s bool m_bDisableWANPPPSetup;9 a4 j$ T" z; q: [: |7 x' W ?2 x
: s. B8 h0 j- X& M* y. G" i6 [& i F1 C
};
/ M, t: `1 W' ?7 d" _. E( `7 U3 k. G. Q0 `. x$ N( X" i* W0 r
+ G9 I/ _. V5 b8 I$ A2 M# ^6 r// DeviceFinder Callback
, h2 Q; Y" X% R$ O @; N1 O( cclass CDeviceFinderCallback7 A6 ~5 H0 E. t9 y0 `& ]7 g. ]
: public IUPnPDeviceFinderCallback
0 v/ @5 C3 V2 I7 ]- d3 g( Y X{
/ V& ` W& R+ k5 d9 U8 Xpublic:
" i# D7 |* P3 c7 A8 q CDeviceFinderCallback(CUPnPImplWinServ& instance)% v" B {3 c- f& D1 q5 x
: m_instance( instance )/ m1 E, v4 Q! ?2 j" o
{ m_lRefCount = 0; }" o. Q5 H% B; Z. B. h
" e; O% g2 _" u, X
1 Q2 y) G, n- H# X
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);% @0 B5 \( T" \* C% D
STDMETHODIMP_(ULONG) AddRef();2 w H F$ B- g; o9 U/ V
STDMETHODIMP_(ULONG) Release();
8 M2 s; w5 t& L9 ]8 Z2 j$ \9 [! A1 D* r
7 K5 r4 D, A( y; N. Z# v1 s5 Y// implementation
: }& L* S$ X* v$ S4 lprivate:& c9 L- _3 ]0 J: s
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
+ o2 }6 B y P2 E. n$ Y" b HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);6 v" [0 p6 L. Y# r+ C
HRESULT __stdcall SearchComplete(LONG nFindData);
1 o* \$ u. V# |& v
. U7 b! }% X' n% R7 T' T5 a, B. D1 H& G5 ?
private:
; c4 d3 X2 g1 e2 V9 B CUPnPImplWinServ& m_instance;% w9 Z. Y ~5 }% M
LONG m_lRefCount;$ |& [, v, c3 M+ Q" a7 ~& P
};+ b- B/ n* ?1 D% w+ o# L
: k+ V# L( y0 V# |4 L
% ]- V- ^0 Q9 f; M; p// Service Callback & Q1 W$ `& j, v! u/ z+ P2 L
class CServiceCallback* V4 x" Y, I( Y* [; I# d% @& e% w, I
: public IUPnPServiceCallback
J; W+ P# M$ @& |# Q{
0 J7 X) Y/ u& j- |% y1 zpublic:
! x+ e3 U/ w( @& P CServiceCallback(CUPnPImplWinServ& instance)% p+ `( W) K! `
: m_instance( instance )
8 r5 G, k) P4 m* T { m_lRefCount = 0; }
9 G. L9 Q: A T! v
) j. N2 K; z D STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
- w0 a( r* \: L$ ?" C P. Q STDMETHODIMP_(ULONG) AddRef();
: Q9 u8 ^" V) c" M& x6 f' ?& h, q0 b STDMETHODIMP_(ULONG) Release();) p$ N& [. `* n9 ~
+ q" i5 Y0 H' \( Q- i m
3 C5 o; h2 w+ V. ?( f// implementation
0 s( q" `* n* X" k% k5 \. J( T+ |private:
, X3 i1 J4 c6 w- y) L1 _ HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);$ R/ M$ v) p \) [" e0 S0 s# H
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);) ~, x$ x6 A4 \; s1 y0 l+ \8 y
g6 B$ J2 \0 d) R1 T( A! M8 E+ A |- ~+ f' l4 n3 o- o" _: F( x
private:( s3 o; Q7 [8 L9 O! z
CUPnPImplWinServ& m_instance;2 |: q& N; A4 z! R) f' K
LONG m_lRefCount;
7 U/ I# t/ D) O};
) ]9 [- ?4 E3 l* z' m
4 l: @7 w- u$ k$ @0 `; V( M6 u( `
7 H5 @3 B! r, p* a9 S0 _/////////////////////////////////////////////////
3 N7 M `3 t! D
% o% h! p' _; i* h4 _- o% F2 s8 O! Y |) s! \5 u* Y
使用时只需要使用抽象类的接口。
4 B; k: ~9 l2 e8 H7 k! BCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
" O$ |5 }; a" p! p. K9 YCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口." H; \6 E1 k" u, B8 H/ r: N
CUPnPImpl::StopAsyncFind停止设备查找.
1 c3 v& x3 Z1 ?$ E0 J* kCUPnPImpl::DeletePorts删除端口映射. |
|