|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
1 u9 [. ~0 b/ ` F1 e: Y
. Y, b( D; ]( r1 U, {& D; K$ w5 c5 o& ^
///////////////////////////////////////////
. F. L& |. w( @$ U2 p//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
- [1 A' ]: X/ M8 u& Z: j
8 z7 |. v4 i; P3 _$ S
, a" _% `) y, r#pragma once
}' S ^ W0 h1 e4 [1 a, O( }#include <exception>
6 v& |% A1 l8 Z# m
9 K7 ]( V; k" s
4 C0 h' u1 I* l a! a. B) A) S2 a enum TRISTATE{
7 e& R) M1 a' t% V2 f TRIS_FALSE,
% s+ B. z3 D6 {. a0 B TRIS_UNKNOWN,
9 F/ |2 X' W e2 Z- F* L5 L) | TRIS_TRUE) E6 j. j* j) q/ @) [
};" V, n, G/ t4 i7 b' ]. F& _% O
* a* p$ O8 r& B7 y3 L& X
/ X) M" T$ Q+ Q4 a; E- ]* r9 N3 penum UPNP_IMPLEMENTATION{
$ a. p' C5 Q9 o; d; A y UPNP_IMPL_WINDOWSERVICE = 0,
2 V- @) U' F6 |0 _ UPNP_IMPL_MINIUPNPLIB,
2 [; ]0 X4 D& o2 P7 i; G: ^ UPNP_IMPL_NONE /*last*/
- m' l1 S! n, V( Y6 a5 {};9 I# M0 {# r1 R( `: ]) l$ }1 ^
) T8 R( ^+ \9 S
+ ]* d, |) R! J& G* B) E( Q9 B1 O7 v* @! x
% M( F: h# v3 @9 w- r5 R" `& ?class CUPnPImpl
& {/ o5 a t: i$ ~1 ?- \1 j{; s' u5 v7 {% s- t3 Q' h
public: b1 `) [8 _% f* g4 v
CUPnPImpl();* v1 w, K8 x2 I8 { x+ E( E
virtual ~CUPnPImpl();& ]1 B- q1 ^ _) e( j8 X: f+ I# h
struct UPnPError : std::exception {};1 O* n* t3 |/ q' Q; Q) c
enum {
2 n6 Q6 ]" c! u: i UPNP_OK,% X8 [0 l: P: f- T1 T% q! Q
UPNP_FAILED,
3 y* V4 O0 q! Y& r7 ]' `6 | UPNP_TIMEOUT
. _3 y. N, t4 i4 {; w( l; V };- `- |0 b/ o6 l5 q/ }- e, y
& R2 F7 O) k) s# n9 M
% @ A P" E) }! E/ k8 M virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;: P3 P7 f2 {5 |0 \
virtual bool CheckAndRefresh() = 0;- q4 C' V. {; g6 l" g) O, R
virtual void StopAsyncFind() = 0;
4 L! U$ P. n2 r4 \4 P virtual void DeletePorts() = 0;% D1 K/ ]! Y7 i; L% g% O0 h
virtual bool IsReady() = 0;
) F' X+ {$ v) ^1 Q9 U virtual int GetImplementationID() = 0;8 [% Q1 C- n+ z7 I' E
6 g! ]1 u$ o) a4 J3 w! M; c. k3 Q) ?
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping9 K/ O) |( H7 W/ ]$ c% G0 S
2 n/ _) |6 H& M0 Z& { e4 U3 A4 I7 m- r8 K( m
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
& I/ k0 R2 {# q$ x1 L( c1 ?# w0 L TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }, d3 a/ L8 V6 N& e5 q
uint16 GetUsedTCPPort() { return m_nTCPPort; }
/ ]. u' j# H ^. F l7 f7 a5 C uint16 GetUsedUDPPort() { return m_nUDPPort; } - a8 F0 m2 }1 C! O( Y
, f+ y; A/ S- z. t# {$ ^
9 k& y( L, r$ E( ^0 G3 Y2 |// Implementation
1 x; I: @) s0 c3 A' @3 a; Q% cprotected:+ t& P' e# K+ e% w
volatile TRISTATE m_bUPnPPortsForwarded;
& f& e3 {) F- Q' K void SendResultMessage();7 e3 y4 }2 _! ~
uint16 m_nUDPPort;
& d2 R* ?# Z. C& a7 S& u uint16 m_nTCPPort;
: R1 U1 V2 B! ]6 }6 x P! g) R uint16 m_nTCPWebPort;
% C" c% [1 A0 f+ E) `4 W# J bool m_bCheckAndRefresh;& }7 V$ s; B9 J# U! N9 ^8 j3 W/ N4 |
! F( H2 z1 p( F0 h; q" G
0 G* B+ y9 F5 \$ qprivate:! r1 b' \( j9 `9 V4 A/ g
HWND m_hResultMessageWindow;
3 [! ^ E5 ?8 X, G/ R2 O6 p UINT m_nResultMessageID;
2 i" V- F3 G+ s$ b& T' O+ l& \6 U5 K2 u i; M, y/ ]' B
! G/ a- V/ H* q+ ?8 Y8 r
};( v: [) `$ c+ e: {- k
1 X/ m8 L0 B- \$ S3 r2 q% P# K" R# C8 H- y6 O
// Dummy Implementation to be used when no other implementation is available$ U- @+ v5 L! @
class CUPnPImplNone: public CUPnPImpl
+ Q# [+ a5 t( K' e P3 l0 ~{
: \, W N- E$ t% Y5 a8 ?7 w9 n4 u7 opublic:
- b. h: O. m8 X. m0 M* P virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
1 f- \: i2 c4 K9 R+ n- F$ b; x virtual bool CheckAndRefresh() { return false; }) G- I- d& k2 p. W. _; }3 @) k
virtual void StopAsyncFind() { }
1 G% z# E- \# D7 d virtual void DeletePorts() { }
3 E2 {9 E, G/ N# ^0 s" J5 ` virtual bool IsReady() { return false; }
" {2 Q) g7 x) _) ^. ]* C virtual int GetImplementationID() { return UPNP_IMPL_NONE; }' s/ D9 X% f, ]$ [
};
- y0 N1 u l* {9 z, {: {6 x3 L
( [$ i- r0 \$ \9 f. z4 T9 L: t: j' b* O6 X% N4 [
/////////////////////////////////////
+ L. Q* |, y4 m1 H& e) \//下面是使用windows操作系统自带的UPNP功能的子类7 e" a1 J! |1 Q& o) f& o8 h
4 y) h" G; {* V2 N* G" l
2 l* v# H* T7 d, H+ l M. {7 }+ P/ B
#pragma once
2 y) N' Z& ]* M; P3 ?$ a7 ?, H& z; K#pragma warning( disable: 4355 )
6 Q0 T7 Y& q- v( l4 H4 S+ N$ i$ i0 P' }0 O1 \
) F4 j, t9 S9 D4 C+ z" x#include "UPnPImpl.h": P- z3 ~, {/ P; T {, \0 Q+ y
#include <upnp.h>
# V0 T" [, x7 B, T& E, Q* D, ]#include <iphlpapi.h>
; g( F% k% B' M8 V- @#include <comdef.h>2 Z6 P, r: k7 R: }
#include <winsvc.h>9 ^6 @0 j6 s/ W: }$ W/ t5 ~ [
$ V, b }' `" S% p' W7 J1 d- a' A/ H
" S, l0 j$ s) A0 z0 {
#include <vector>
$ V9 h# `* F$ ?2 k$ w#include <exception>
3 ]7 u1 L! \3 ~- r1 \4 e F#include <functional>
$ W" R0 c& _7 r2 k7 e
% }- K$ M; l& {8 R; }: V. {& @
2 ^/ w5 p& W; L; @9 c, J
Z' X& z; w: p4 B: s& B$ `8 i6 {, m: d3 H3 ~# n, i
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
2 t! ?4 ~1 i9 z! u1 j1 s+ P/ W" xtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;8 E9 h9 ~! t0 C7 N6 B U
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
& f; j5 ]( c4 Qtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
h! d5 {0 Y! s& A+ z5 Htypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
- d( X& l* T$ u% t# o4 g& Gtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;4 p; b1 ?1 H6 V
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;2 O. a" k e% k; v- x
$ _6 k' B; n7 I) I4 F5 w
1 r8 h) v6 Y V% O( X3 \typedef DWORD (WINAPI* TGetBestInterface) (
1 a3 D# f9 ~, v IPAddr dwDestAddr,
! G( d& r, m1 g& t# W) z PDWORD pdwBestIfIndex3 _' S% s' y* D4 V
);
$ Q0 m6 i% h' }, F" C: O5 i% ]' b, c7 i1 G% j1 E! J0 L4 o
( y6 V9 ~" L4 A+ Y) {7 ~typedef DWORD (WINAPI* TGetIpAddrTable) (
# c" I, Y1 i' S9 l6 d8 D! p7 p* _ PMIB_IPADDRTABLE pIpAddrTable,
4 ^/ N+ d: z" y PULONG pdwSize,
; C" a5 r0 w' W/ x' g" T BOOL bOrder' Y% J: {4 |) w! S
);
6 S9 Z& o. s' o# j' m6 Y; [3 h( }8 v; s+ o1 u8 u7 g
* R7 q0 D7 H0 F, vtypedef DWORD (WINAPI* TGetIfEntry) (8 m" B9 j6 n3 C$ b
PMIB_IFROW pIfRow
* i6 s) r6 m# y& ], w/ p- a" h$ u);6 e3 v9 A" h% r& p
! v5 f* j( a z( N6 l0 ^
5 m) T" m2 V# i8 p; O) `# a RCString translateUPnPResult(HRESULT hr);2 X" e( S0 |/ r: ]2 `
HRESULT UPnPMessage(HRESULT hr);
' O/ s% d8 x6 z# D- ?5 M5 _$ W3 A6 J
4 m7 c6 |. k+ c: o5 \% a; r+ B: { ^
class CUPnPImplWinServ: public CUPnPImpl
8 w0 O# C/ {) [1 F{
/ Y2 W# }$ d. o: [. \+ W friend class CDeviceFinderCallback;
, c; K2 A, r0 S1 V7 F friend class CServiceCallback;+ [8 f5 v* g! E; Q0 s
// Construction
8 u1 _5 ]7 k; h. a0 fpublic:* S* F& e+ ?) r3 B8 J' Y
virtual ~CUPnPImplWinServ();
7 d9 v- \" P+ k CUPnPImplWinServ();, S- a2 P) a' v c
( O' q: c9 Y5 _2 N. w
' o4 g6 ?2 [: U2 _! Q virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }) I! k) Q' |) O6 Q+ i3 o% ~& `
virtual void StopAsyncFind();8 s; w8 R; ]- m8 ^- q
virtual void DeletePorts();
4 K; J3 j% B3 n( t) M3 ^* w7 u0 V5 e virtual bool IsReady();% n- {. `" u% K
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }0 U/ i9 Z( d7 |$ g& n0 K ~
! ?* _3 m" v8 f( {, \# ~6 Z: D# c" m# A! ]2 D6 o: |
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
1 x% B* t4 V( s // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later5 ^. z/ k' {5 h, r# s* r3 p/ o8 X: l
virtual bool CheckAndRefresh() { return false; };
4 D H3 r. M6 A) W
0 w; R$ x. z9 T, H7 X" a& {" D# a6 W7 o! K) e
protected:
' o( Q1 o) G: F( @; ]' y void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
6 r9 n6 K4 X7 X) n) z8 ~9 P void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
9 u* g! T3 U+ g7 u+ H g void RemoveDevice(CComBSTR bsUDN);
1 j' t; ?: X7 A2 _ a t, X$ e- q* c bool OnSearchComplete();+ q! D) O1 y4 U* t
void Init();" H ]1 G" ], j* {+ }/ Y
0 {2 T: r/ M* v& N# i! Y+ }# C) c! v! ~
inline bool IsAsyncFindRunning() / c; V& O4 E* V! k L
{
- ?; S" \. M ]9 e7 A if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
8 e" h# S2 {+ \8 g4 B {
3 v! F/ u2 i% ]. q1 { O4 |# R m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
8 O4 V1 {) A j# P4 S& ~ h! M m_bAsyncFindRunning = false;
. o$ S: Y- J* M) W; L, i }
5 C6 I2 W d P$ g; Z; O1 t MSG msg;* M3 D9 O1 o6 j
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
: g" q9 D" p3 c$ G; }+ T5 L; p+ m {
: S% g7 D# w7 p TranslateMessage( &msg );
4 `' }' t* D! O: F8 |' C9 o DispatchMessage( &msg );+ L" Q! V9 }* _$ v( r e! N
}1 ^; q( b/ B0 z' n" T
return m_bAsyncFindRunning;) {# N( e# h/ A. d& e
}! K2 _ `7 \) {; r5 \ i% r2 w m6 I
+ D" z% \' J8 O( r' M: `0 j! f4 U1 O0 v) q2 ~) h* f% Y' h# \& d$ ~
TRISTATE m_bUPnPDeviceConnected;7 R, q3 @7 o. v6 w7 s7 t
* O: h- }, b7 p9 H4 E
4 X! h2 D+ M; v8 S' S9 Z5 e
// Implementation
% d) V$ X2 Z" J7 d+ { // API functions
v% c) h& P, Z/ e5 Z5 `3 b0 Z( { SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
0 Q9 s: x; Q/ H0 A: j& `6 I SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
0 I& X6 v! ]) \1 t BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);1 q1 b7 v0 C8 \& |
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);% J& ~/ i' J' P4 u+ R7 d
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
7 `$ ]+ o* o, [4 X" X BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
) [: R% c! _7 {0 G$ N
+ | ]. x f" ~) X- g! g, a0 U
L; e0 Y; B7 e1 |5 A TGetBestInterface m_pfGetBestInterface;
1 ^5 D+ ^4 E' p, T! p TGetIpAddrTable m_pfGetIpAddrTable;
9 g/ |) M0 S- @6 k$ X TGetIfEntry m_pfGetIfEntry;
% v \% f: K" V4 v- C( I4 E
& a. a( G8 B% \- O5 ^4 _: T
* {2 O/ a( `; ^; o0 T# m; i static FinderPointer CreateFinderInstance();/ v1 J3 ~& x2 ^4 A4 i
struct FindDevice : std::unary_function< DevicePointer, bool >
+ ~4 V9 @* I( Y1 t' Y l1 U' L+ ^ {2 [( v" P% x# N4 ?0 K
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
/ o5 O: ~ [% A2 a result_type operator()(argument_type device) const+ d$ ~7 z7 c4 Q" o5 I" f6 l( L
{" f( [7 O4 ~. P' ^$ [ r
CComBSTR deviceName;
! O3 G6 A W, u+ E' e R) ~% Y HRESULT hr = device->get_UniqueDeviceName( &deviceName );, P, |' {. p/ S$ T& v
) g) \; R) j8 G
. \6 w( x1 W- U: x
if ( FAILED( hr ) )
8 r, H$ _0 Q. E) E, t return UPnPMessage( hr ), false;
' ^( F3 k# g3 E- B1 I; s' r+ a! t, y; D
9 n; y' p6 q' Q. B0 Z return wcscmp( deviceName.m_str, m_udn ) == 0;
' C2 d" y; O2 v: K }
$ n9 I! R3 Y" e* w) S4 E$ Y9 l$ D, b CComBSTR m_udn;
( m( O/ Q$ @$ L* F- s& Y) ^" p: q& b6 V };
5 f1 G9 n! e" L- b2 b: H
( K5 ^6 U( |3 M7 P7 _9 D7 [ void ProcessAsyncFind(CComBSTR bsSearchType);# i- E5 b- t# z
HRESULT GetDeviceServices(DevicePointer pDevice);
s7 ^. o. O7 X7 m6 P void StartPortMapping();
2 w( K+ f" t7 M HRESULT MapPort(const ServicePointer& service);
: T2 S& i8 J9 l% s4 D0 R8 L) V void DeleteExistingPortMappings(ServicePointer pService);5 `2 P0 f% J) c9 y$ b
void CreatePortMappings(ServicePointer pService);5 q& Y, [1 L5 }$ O& S
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
7 h. }9 G. D6 w1 ] HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
+ S. {0 i: P( e LPCTSTR pszInArgString, CString& strResult);2 K2 {$ F- X6 i$ ~+ O
void StopUPnPService();
" B2 g9 ?: O$ w. F# P$ r+ b# `
+ ]3 N1 W" `/ ?) V* k2 ~) s8 X' j [( _/ \8 ?1 f2 x! H5 ]
// Utility functions
" ~- `* F. P% J+ \" z- J l HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
8 k1 Z5 w/ W; ]1 R INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);1 u$ h+ u8 l$ I8 {3 Q
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
# i: @. V. w4 x void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);1 L8 [) U! q. j* m! W& C1 O
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
! p* }, ?. f: S( Q' {- k: X/ x( H HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);% m- A6 ~; Q" o1 v/ \ o7 m
CString GetLocalRoutableIP(ServicePointer pService);
" [5 {/ r5 J# @8 b/ I- i
8 i9 D5 h3 u: n7 U8 p* Y8 }. |, j8 g8 i, y7 V& ], h
// Private members" H& j2 C$ z4 O0 A
private:' d8 x9 T( P$ n0 i
DWORD m_tLastEvent; // When the last event was received?
% T F5 m* K4 P2 N! u. n std::vector< DevicePointer > m_pDevices;5 N, j' r7 X4 Z: a: a$ h2 Q& P& Y3 Q4 v
std::vector< ServicePointer > m_pServices;4 P- p; T: t; `% C6 W- f t6 L
FinderPointer m_pDeviceFinder;
6 E% ?2 P7 e, Q DeviceFinderCallback m_pDeviceFinderCallback;3 ]% z. D0 q# G# W
ServiceCallback m_pServiceCallback;( W; Z: o* S5 e3 U
* P. N; \) A' A* r I! H6 l
) I7 Q1 A0 w; k1 P LONG m_nAsyncFindHandle;6 `# ~0 x* U) O% \ B
bool m_bCOM;- { u) B5 Q4 e) Q; N
bool m_bPortIsFree;' @+ B1 u# }8 N- l& `
CString m_sLocalIP;+ w! U: z6 c$ P
CString m_sExternalIP;
) a4 c1 X& N2 v6 s6 L bool m_bADSL; // Is the device ADSL?7 t! w2 e7 A" ^7 O1 a
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?4 E- Y( U( p: [- Z
bool m_bInited;' D/ a( U X* ?0 c4 z
bool m_bAsyncFindRunning;
, h# O9 n# u7 \/ ], o7 P HMODULE m_hADVAPI32_DLL;
: L( l* B4 u, e. K4 }1 b HMODULE m_hIPHLPAPI_DLL;/ h: p# w# Q: w6 Y- d# S& J7 W
bool m_bSecondTry;
% e0 {) G$ k! W) E: d- r bool m_bServiceStartedByEmule;3 r% S, l7 q0 w1 ~: d, W$ Z
bool m_bDisableWANIPSetup;
) w/ T0 Q9 X0 i/ { bool m_bDisableWANPPPSetup;+ F4 M. T; }2 t5 s* m
# B& L4 Y9 F+ c+ C: F
0 j5 ^+ B, E: l) V};
4 T1 ]3 H" h+ g) T" i5 {+ Q
, d( g0 m0 }' A/ E8 e5 U6 u, o5 s) G1 b: B
// DeviceFinder Callback
3 s* X9 x/ n5 x( r8 J3 aclass CDeviceFinderCallback' o1 J9 A. {. ?8 O* u! t
: public IUPnPDeviceFinderCallback
5 S* E0 m* b! T7 c! n{
( q; n2 }6 u) upublic:2 [* S( T- J, k d
CDeviceFinderCallback(CUPnPImplWinServ& instance)
1 [# ^( L; G; E" ]& I, L' X : m_instance( instance )
% ?$ N' P f+ N# A { m_lRefCount = 0; }3 ^; m9 L a J+ ~
' T0 U4 K& K0 u
+ e4 f ~" c8 \ H STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);4 ~+ Y8 I, a5 T9 _+ T$ `
STDMETHODIMP_(ULONG) AddRef();" s) R6 |. H5 p
STDMETHODIMP_(ULONG) Release();8 g$ |4 `+ S" D, g2 q3 I
5 g6 e F9 s' d( q" Z. q7 O
, v: z3 Q+ [) ~8 _% B8 o// implementation
/ x* `8 ~4 |% N. e" Dprivate:# M! D; G5 [( b" g6 _6 b! e
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);2 r! n" f. e' k$ c
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
# N9 t8 A7 Q" d* Y HRESULT __stdcall SearchComplete(LONG nFindData);
, X$ S7 m* d* L# }/ t- X" h# M9 f2 J( U+ X0 G: ]
; S6 u% K: l c5 V) _private:2 R P( i1 u Y
CUPnPImplWinServ& m_instance;
' i! Y5 v* [8 u/ C LONG m_lRefCount;
) M3 W9 Q! J" a6 t L};
; {' j) O) G. h c& |6 j2 [# I
. s0 W8 j7 Z v
$ G6 @& D" f% {, X: G) o( f- l( Z// Service Callback i J. ?& e" n1 [$ F- F* p
class CServiceCallback
. ?4 l7 Q ~7 y0 R- _) w : public IUPnPServiceCallback
. |& k f6 R0 E' W7 _{
! Y4 ?- I# |3 o; V3 vpublic:
5 i2 {; ~! f# C CServiceCallback(CUPnPImplWinServ& instance)
5 j# F, b9 H$ v8 q# T# E' E y : m_instance( instance )
. D/ B# ]8 e- \) |5 k { m_lRefCount = 0; }: q/ v( \ [+ {* O/ U: K$ D$ P
8 q6 Q0 U: S: Z9 ^% F STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);" b4 D+ W3 \5 l5 x
STDMETHODIMP_(ULONG) AddRef();
l/ E ?$ ]6 M STDMETHODIMP_(ULONG) Release();
1 y/ H! o" q- c) j+ m
. x0 ]# F0 C& S$ E. J7 K% ?7 r% B E2 h3 B. n
// implementation
/ g5 P' J) M- @; g6 \2 _private:7 r# ~% U0 T! ^ n% E8 n( f; p3 G
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
" ~% S% I' @* H) I/ r Y# m p" S5 O- M HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);) i% [! j4 a1 `$ h* m2 r$ I3 q7 D
0 C: q) b+ P$ c
- P! e& T& m) l' R2 aprivate:
# W5 L( w; g0 \7 m0 i7 X- N CUPnPImplWinServ& m_instance;
; _# x( U# y% u/ J8 \* i# q LONG m_lRefCount;( T* l7 t% M% u' S
};* ]9 y& k+ O+ i' u: y
7 R* _! ]; P1 V& T' }# b
( w' j" c5 ~6 g6 ]
/////////////////////////////////////////////////+ W) b5 l3 L; e; T, ^$ w" B
) {# B6 b3 H" l8 R1 N6 V2 E
! R) V: a/ n( I: u0 L q! M
使用时只需要使用抽象类的接口。1 I5 ~4 y. N/ a ~5 Y. g
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.; J' C! q, N! I7 x/ D
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
! V1 l: c. `6 j3 ~; q L0 c0 |' wCUPnPImpl::StopAsyncFind停止设备查找. u, _: ?* o; J) s- N% @6 ^
CUPnPImpl::DeletePorts删除端口映射. |
|