|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,8 u& h6 ?! g9 |3 P' I
9 D, P0 o8 A0 g6 j! b8 w, ^7 h
1 U% {3 Y- N. s$ h# z+ j
///////////////////////////////////////////2 h! ?1 K' e; V. B
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
6 \+ N8 Y3 f# v0 e) J5 L) H9 q( l d! w, i3 Y
6 U. f! H" I8 b( f7 i- c- ]5 f/ A' @#pragma once
% ]# `/ J* q/ A, K. r#include <exception>1 S% l& a$ H: G( u: G* Y
' D5 p# ^, k7 _; x0 [; {" M8 Z# g( P
enum TRISTATE{, Q! _8 }: {7 g+ k
TRIS_FALSE,
% c0 N2 `/ v+ b/ V. | TRIS_UNKNOWN,
6 R. z) @. `3 {: P- y1 S9 ~ TRIS_TRUE
9 I7 _& E" D7 u6 D};2 R ?! q. s1 Z4 c! v
& _ u9 ?) v9 w
0 ^* ^, \+ W# l* p- ^enum UPNP_IMPLEMENTATION{
4 e& a6 N0 u! w/ e" m/ y+ @ UPNP_IMPL_WINDOWSERVICE = 0,
6 O9 \5 [) S j! U, Q3 B UPNP_IMPL_MINIUPNPLIB,% g" r T( W( A, @" D6 s7 S
UPNP_IMPL_NONE /*last*/
; ~4 z, C9 e2 g; E# m& H2 l& `2 R};
9 }, W, V, R- v! T( }' r& Y A) d v/ }3 G4 G5 Z; q
, t/ b# T" o& P' Q* t
X& Y3 w' K7 z! T+ }% G& H; M+ {8 W
! I. E* u4 @8 `* I% D) ~class CUPnPImpl
8 @2 c6 |: j" S7 J. T0 S& p( h{
8 v) Q' W5 q/ jpublic:
8 U" u$ z. V. k, Y5 S) C CUPnPImpl();; R( r- k9 @( w1 Z7 R+ R. ]5 f: j
virtual ~CUPnPImpl();
. s) u9 I) }8 V/ O0 v/ x struct UPnPError : std::exception {};, N3 g0 G" Q! N- u
enum {6 a% v! L8 l7 l0 m0 z
UPNP_OK,
) I- `$ ]! d0 A6 O7 x; m& s UPNP_FAILED,
$ O4 t4 r, |/ D( R UPNP_TIMEOUT0 _7 J: ~, W9 L3 \ J2 Q2 V
};1 L, m; Z4 o; ^% X; N
9 U3 S+ Y6 S8 O$ E/ A
0 r7 Z6 H8 {" A5 F; l1 H
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;1 N! M( M, J! O7 Q6 v1 n7 u8 w9 v
virtual bool CheckAndRefresh() = 0;+ }$ k* i6 f# U: }* ?1 J1 ]5 Z
virtual void StopAsyncFind() = 0;7 |/ t, u- O* J5 M% L
virtual void DeletePorts() = 0;
/ f0 j+ C$ n! P! E& O8 ^- F+ J virtual bool IsReady() = 0;9 L: ?, o# v7 `4 e( s
virtual int GetImplementationID() = 0;
" V7 |# a9 [/ _! V1 C
$ T, s$ g0 j5 z, q void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
" V [, m1 S; v0 n
2 ?1 s0 o i& S( Z. _; J7 D9 t& ^- V
" H) |+ G' A( v8 {% z void SetMessageOnResult(HWND hWindow, UINT nMessageID);
5 H8 |/ D' J" q" }4 s: W TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
3 W% l2 B0 `6 v0 ^ uint16 GetUsedTCPPort() { return m_nTCPPort; }
% ?. X4 x. O8 [; v$ F8 r' ] uint16 GetUsedUDPPort() { return m_nUDPPort; }
8 S4 z& B2 B# ?. o7 K% T* W/ v+ Q. w, F) j5 z$ d, O( ?0 X& Z! M
. c: g I6 I% o
// Implementation
f/ o' @# ^5 G; ?+ C& F# E. v, Tprotected:7 I* W/ u. Z# c4 |0 X% z
volatile TRISTATE m_bUPnPPortsForwarded;
# A' W0 L9 L- W" R/ A! J/ f void SendResultMessage();
2 U7 T* u0 P+ K; d4 v uint16 m_nUDPPort;
* T6 n* S, c2 H uint16 m_nTCPPort;
; i. O% Q* v! X2 Q5 Y, h8 h uint16 m_nTCPWebPort;
6 d5 F) h8 i4 b4 P2 A! f( I bool m_bCheckAndRefresh; M* Z( D' I; [3 g
# l h1 C/ ]6 Y+ i. C5 n8 |
) d3 c" ?: H/ K3 Rprivate:$ u) i' @- t& f8 l
HWND m_hResultMessageWindow;
# |3 K5 |' A3 a! _# q9 ~0 M UINT m_nResultMessageID;
0 b9 o, e; x1 c1 W, v+ y+ a4 v. i/ d; Q6 W% r, z- E
, m! J, z( k9 e0 O4 l};
; @2 N) `5 E) L- o. x: R9 ]
9 @; w8 l$ ~- H& @- A* A7 ?8 V i& L! d6 t
// Dummy Implementation to be used when no other implementation is available
$ Q: c/ n" U# U: e/ X" ~class CUPnPImplNone: public CUPnPImpl8 x$ N; y3 g9 J2 G# o9 w3 s5 o
{
. V+ b8 q/ i+ apublic:
4 ~0 P1 [1 [* x3 s- w virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
. i/ q- R& V0 E virtual bool CheckAndRefresh() { return false; }5 k# c) @7 z9 k) u, D& z) b3 Q; I
virtual void StopAsyncFind() { }
1 j# z# K$ C3 @$ H virtual void DeletePorts() { }
8 d( u+ t3 y' v4 J virtual bool IsReady() { return false; }! ]3 b. t/ t. z- k- p2 R8 |
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
! s& O3 ]3 T ~3 O: s};
4 q# {8 }3 t' d1 q, }, s" @
) t, E) ]9 R4 }* L) n
# p" {* `7 j* ?, A& j. d/////////////////////////////////////
" v( g6 `/ Y1 H. i& i6 m//下面是使用windows操作系统自带的UPNP功能的子类' `. r' V& k4 T/ I
' d$ Q3 W4 |% f: ^% I
. T `8 E0 O8 m
#pragma once
# `: ~4 r% Y# }+ j! w4 N6 o6 i#pragma warning( disable: 4355 )5 x/ y1 H+ l9 @% ~* B- a0 G! E
$ S% k' ~) h: C: A* A
% G5 {% W/ S# G; O1 n/ c; l$ W#include "UPnPImpl.h"
% `/ g0 ^0 x% H+ P8 c2 K1 \#include <upnp.h>$ ~% R. _5 V+ Y) j% I
#include <iphlpapi.h>
+ e+ D4 o( w' \# e [% j J- D* L#include <comdef.h>
5 R; P* O$ S' \0 E" y& D#include <winsvc.h>) r$ D: W( ^: j' q
" a! X5 A& [( v3 L* `
, q3 i4 B' w% U! E. c/ z o" w, E
#include <vector>
3 b! |% `5 D! q% K#include <exception>- U7 G/ }0 c: p3 {4 Q
#include <functional>5 X& O$ f) I; G- Y# b; M
$ G V9 T4 L6 q. }9 W. Z9 ~
8 o+ j# @% C3 e7 R# [* I+ I! ^3 S1 E5 t. L$ C, p4 T. r+ \' z1 l# i
+ L. ^: ~4 [/ X, m& w+ {
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
, Z2 ?' D6 p! Ttypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer; F \' X4 Z \! t
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;6 J2 c6 x7 g# C6 ~9 n9 K# R
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback; e8 n( {2 M+ O$ v) }
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
3 l* k/ @0 |; t* _# `5 xtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;; Y9 q6 U& J8 O5 h Y
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
( _( d% h; n# i/ ^2 F) W8 y) O4 i
. h# [5 |1 z# l: Mtypedef DWORD (WINAPI* TGetBestInterface) (
9 u' W& p) \( r9 G: A7 x IPAddr dwDestAddr,
3 d+ u r/ f. t9 K$ C; X' w PDWORD pdwBestIfIndex; l# O" s0 ~, x/ N/ h/ O% p6 R# {
);
% j8 W5 c' `- u7 s
; ]/ B9 @+ L/ @" h& B* Z
0 g7 t" ~ C% e2 Z" B" a2 q6 itypedef DWORD (WINAPI* TGetIpAddrTable) (8 M( M. j6 r0 `& g
PMIB_IPADDRTABLE pIpAddrTable,
5 {. T: c; z/ L) W8 T" V7 `8 t j PULONG pdwSize,9 G x6 \0 |% c( G
BOOL bOrder% n$ i5 a, c/ k% O
);4 L" h, I: h: t2 j, P' ~
% Y8 \0 b1 P3 H! F: Z' R
: D0 z0 T* I E, G( o3 htypedef DWORD (WINAPI* TGetIfEntry) (( }2 _ [( L% f5 y) ^5 \
PMIB_IFROW pIfRow: z: a, v- p$ M0 f, z& m
);
& M* b {' m- `, l0 J
& k1 N1 c+ d! E* h: e1 Z
- r9 ]/ u+ X& u7 x2 T/ P3 LCString translateUPnPResult(HRESULT hr);' B! l8 p, o* q
HRESULT UPnPMessage(HRESULT hr);
- i( e) _) B. B+ g: U( d, u) c* w
: b4 U4 M* x, x( g9 \2 w
9 y w9 U: N3 X% t& uclass CUPnPImplWinServ: public CUPnPImpl
9 T$ {+ _: K1 \{
, ^& _0 Z% a. N2 n5 {7 b1 m8 P friend class CDeviceFinderCallback;4 {5 i! N) |9 ]6 o* U
friend class CServiceCallback;/ P# `: X9 W7 S- V( r
// Construction* j# {' Y* X( S7 \! z
public:" ^* B! W: r2 v% k% [
virtual ~CUPnPImplWinServ();* Q) A# m8 X. c3 M$ c' P1 Y
CUPnPImplWinServ();- D; a' o1 Y6 q) [9 l X6 D/ l
/ B: e9 Y; b& \8 L. X+ O0 H) m1 I, A) {7 Z! A. {% H: D
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }8 n: M6 [7 w" {, G* K# N
virtual void StopAsyncFind();8 o! y& v. l2 u7 ]# q2 y' c( y$ j
virtual void DeletePorts();( x2 I9 Z* T/ }9 W* m
virtual bool IsReady();
0 f1 P& r9 _4 f2 x& y6 @) F* S! [0 ^7 Z virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }- e2 \, U- a) Y+ `8 `
( W% p& {5 R3 L) s4 N! c
8 p; @0 R( Y6 P+ M g // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc): P8 W A; n) X J% c8 R% K( e8 M
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later5 K5 M' n g6 K0 G+ R
virtual bool CheckAndRefresh() { return false; };
9 U( U( S9 H. }, S1 Y- o5 j. k8 @+ ]5 `) z" U: Y) h3 a
: {) F1 R% X& z1 m J. Q
protected:. X# L* Z/ L9 V2 G7 B
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
4 n: P. T b3 x) a* z1 g void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);6 x6 k4 G* `' Y
void RemoveDevice(CComBSTR bsUDN);; j4 e1 |; j% f7 S; o0 ?5 S- w
bool OnSearchComplete();3 R5 N" G: [5 ^5 S$ T. h6 {4 k; V
void Init();7 B" }1 O4 o6 r. |. T x
- q! A6 E( n6 l& f# x
6 Q/ R* c# k t
inline bool IsAsyncFindRunning() 2 B) O5 ~5 A$ D8 w
{$ y& U1 p3 j/ l+ G' Q( U' S
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
4 ^' _) p( ]* P& @5 T E {& x2 {4 C- t* W; p1 \/ E4 p$ G! r
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
! M1 e/ V' \2 m m_bAsyncFindRunning = false;
+ }" T' I; | O8 g' y0 { }
. `6 Q' R% ~$ J4 O MSG msg;
9 B, ?' J9 O5 C7 w3 [ o. _4 p4 ]. _3 o while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
0 p) k$ V* [3 x7 a4 C {
0 O& r4 ]7 M* ~) z TranslateMessage( &msg );
# b! ~/ I. R# }( r; w5 Z3 F# U. e DispatchMessage( &msg );
" F T- c/ x4 c9 S }. i) a6 r9 o6 X9 W
return m_bAsyncFindRunning;- X+ U0 c/ j: e
}
) c1 ], M% W4 i `
% c% c Q% f( M8 y$ U% [
/ Q) W' J" W; M, h0 O* t TRISTATE m_bUPnPDeviceConnected;
7 s& h( \4 T x& u5 ?" K4 _. P4 a) n4 G- Q2 R8 k
0 Q; l- x" ^3 c0 L, \- T
// Implementation3 ^& U* ]5 A" v
// API functions
+ b6 C9 o, `. q$ {! \# F8 Z9 t SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);3 ?$ g; }9 W" N6 R( [
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);) |6 C" v8 O5 G" g) N* j" [- `
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
4 z: W+ H( O ~/ G BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);0 d$ Z. b) b# J3 g7 M; ~
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);9 E. h/ e& b- g, E x# ^
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
8 x ~6 j" N5 V) [
+ e! q7 U- \9 |% x* Z7 k/ c2 @1 q. m! ?/ l- |( h. u2 P
TGetBestInterface m_pfGetBestInterface;2 j7 n& p% f; h4 H4 d# e
TGetIpAddrTable m_pfGetIpAddrTable;6 T2 Y# b8 R( @' S2 l1 ~: ~ i9 l; r
TGetIfEntry m_pfGetIfEntry;
( {% o3 f) t$ G8 l; t% W! I
6 a, @; d0 K, {+ s9 x6 \8 @) d: a7 S0 l- G! T1 h) ^
static FinderPointer CreateFinderInstance();
n) k* Y0 \4 a; | struct FindDevice : std::unary_function< DevicePointer, bool >! d" M7 ~% p+ Q/ |: ]0 {$ L T
{
; |/ R' M; @0 z6 A: q FindDevice(const CComBSTR& udn) : m_udn( udn ) {}& }: M q& r1 H" {8 L1 H- e3 j) a
result_type operator()(argument_type device) const) i& L3 ~9 I% @5 v0 S
{
8 P" G& R- a8 X: t7 D3 \ CComBSTR deviceName;
2 v: ` m' t6 ]3 _- K' X, t/ J HRESULT hr = device->get_UniqueDeviceName( &deviceName );+ \; k) t# O" x* j' J( w
2 V, u+ I# D4 |4 u, J) `( u3 X4 M4 p% n. A( ~; Q5 k
if ( FAILED( hr ) )
; R0 ]! X% w4 e6 ]+ c return UPnPMessage( hr ), false;
3 h# K- ^$ {3 A6 w. a7 n. w2 D0 }" y1 `( ]! {
6 U4 u, q2 s, _3 b! V5 X3 B return wcscmp( deviceName.m_str, m_udn ) == 0; F7 A- O! m* _% ?/ K
}5 Z9 _$ e" d! }- f8 t
CComBSTR m_udn;1 V5 p) i& A* ]" S# C5 d5 ^
};! m+ Q3 B1 N# e% i) ^
e1 r8 Z+ t4 n m' G
void ProcessAsyncFind(CComBSTR bsSearchType);! M+ d; b: c; |7 r) M6 |/ P
HRESULT GetDeviceServices(DevicePointer pDevice);
+ ]: i/ B8 n5 T8 C void StartPortMapping();
0 k6 c* H& C8 W: c! r HRESULT MapPort(const ServicePointer& service);! J8 r& e9 Z W% I
void DeleteExistingPortMappings(ServicePointer pService);
: L4 c: _ ^7 \# u2 V$ M" L void CreatePortMappings(ServicePointer pService);
/ m, L3 L1 w7 p3 V8 {* F HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);- l0 S% u% l. M/ d8 e" [. I
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
, D0 Q* c* g, W: X: u LPCTSTR pszInArgString, CString& strResult);# |) x6 g& X I1 M( W% q: E9 ^* _ I
void StopUPnPService();7 W1 H, n" k% N' o! ]6 F
# Q5 v$ F2 j' C M
9 {4 I& A3 o+ ` // Utility functions
) q, }3 v8 P$ D, ]; N HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
; l" w8 s$ D0 G) o7 y7 Y INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
1 D \; U# F% ? INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);( N5 Y# g5 r6 a
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
* h; \& Q7 |3 r HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
8 p# A, r" H. i2 V3 P/ t3 k" j6 J) _% Y HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
8 Z: T6 t2 }$ `. F. J CString GetLocalRoutableIP(ServicePointer pService);7 v Y2 D5 p! o1 v: |; t
2 A. S3 u0 x7 g) \ k5 k/ U: I
. P4 A. M! i, a) `6 _$ |* p1 ]3 U// Private members
/ V. B; N; |+ G! U7 a2 Q" T fprivate:
: }0 E- t" l7 U# m1 F V2 l. K( B1 b DWORD m_tLastEvent; // When the last event was received?
5 H0 j9 V* i. F: r6 m std::vector< DevicePointer > m_pDevices;2 t) V: R9 P+ P% ?0 K) V1 a
std::vector< ServicePointer > m_pServices;$ E$ ^" B. L" C6 \1 J% C' Z) @5 l" F1 ?
FinderPointer m_pDeviceFinder;
/ h7 x% L( q0 s3 W% y' ~9 s7 F DeviceFinderCallback m_pDeviceFinderCallback;
* M4 m+ K- }- h' k, T ServiceCallback m_pServiceCallback;
$ d5 n/ y5 T) P X0 e
+ P$ {; c5 D. j0 E/ {4 [" [) N6 V3 U& d
LONG m_nAsyncFindHandle;
3 c$ s2 ^0 B; _ bool m_bCOM;: F1 c9 H- ], m
bool m_bPortIsFree;
3 w4 T$ g! S: q7 T) ]0 i CString m_sLocalIP;5 ^" f& q# E% _# x. j
CString m_sExternalIP;8 v1 y6 M7 c- S7 w" b
bool m_bADSL; // Is the device ADSL?
2 |) c. D7 C4 {! g- z) u bool m_ADSLFailed; // Did port mapping failed for the ADSL device?# w0 K7 C9 }# [9 _
bool m_bInited;8 S* x# K3 q7 i# M$ J
bool m_bAsyncFindRunning;
C7 X/ @; U K9 f HMODULE m_hADVAPI32_DLL;( ]$ M3 v \! L, j5 |# w! s1 ]
HMODULE m_hIPHLPAPI_DLL;% s& C" ^$ e) v! N5 E
bool m_bSecondTry;. q% e& j+ i6 u6 Y
bool m_bServiceStartedByEmule;8 a7 x* C. C) e a$ O$ ]: p3 N: v) ?, i
bool m_bDisableWANIPSetup;
, u9 j! Y1 B3 [2 m/ L: c# f bool m_bDisableWANPPPSetup;
4 G. K- |1 B, _
7 d" |. D( S* I/ s* G# Y1 K# @' g9 [; x; T/ w9 ^1 P
};
1 x! r0 K2 O j; i3 x% m7 w1 N! q8 d, Z# G3 f! l$ x
) h2 s& S7 T) i- k+ l: X
// DeviceFinder Callback
! }; x5 u5 A( G. zclass CDeviceFinderCallback
5 w2 ~- \' _7 t: k( f2 ], t$ J : public IUPnPDeviceFinderCallback
1 ^; B! _2 c+ u8 V0 }% K{* \3 }# j' M( v. m
public:8 S2 R+ }2 | `# t/ r) r7 M: z: b
CDeviceFinderCallback(CUPnPImplWinServ& instance)( L& N) |; q( A6 w( ~
: m_instance( instance ), I/ F( Q3 Q% z- T0 k
{ m_lRefCount = 0; }7 E. d3 ~! O7 v: o- h" ^" o5 f4 c
) r$ _3 p# C3 [! s
6 |) [9 O' b% W STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
2 ?5 g* {, u4 X7 s7 u) _$ q8 V$ A STDMETHODIMP_(ULONG) AddRef();
8 m. `2 a+ r$ T- e2 @( |, K5 T STDMETHODIMP_(ULONG) Release();: N! W0 w# K( J8 M- l! I
& w' z% F* J7 |6 Z$ l
) ?2 A/ o: t& X. J8 p// implementation
& S! z9 `' V' `; S7 lprivate:) j7 Q ]& w1 ~8 z* l8 X% O
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);$ ^: s+ e. }: J
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);1 [: Q5 Y( k$ L9 R
HRESULT __stdcall SearchComplete(LONG nFindData);# G) ~: @( U% V3 S/ B
) v/ u" t5 p" ~ A
/ y2 ~; \, y9 H1 g' bprivate:
' v8 M& T( b7 E1 z+ W# \ CUPnPImplWinServ& m_instance;
2 X. Y* z/ }5 z$ D2 \2 ^ LONG m_lRefCount; {9 ]; I! A! t O2 h! Z; ?$ i) @
};
" j4 T. B/ `, d) ^
# B; E) J) A# X0 V' I
3 \. x3 \9 @& n3 ?0 B. a- A: B3 _8 J// Service Callback
% u; @" K4 j% V+ D9 o A* kclass CServiceCallback4 W; ? ~; s. ~7 n$ G$ N
: public IUPnPServiceCallback
3 l$ @* O1 m+ O+ c) S! S3 `3 i{
' E; `' E' J! T7 }* y5 ypublic:
( o$ Z5 `2 p. x k9 i# D CServiceCallback(CUPnPImplWinServ& instance)6 y6 U& J8 ]+ j! \
: m_instance( instance )
( B0 c; `0 m* d9 H { m_lRefCount = 0; }0 ^- W' e1 j, E6 H, i# R; E, G' l( f
: \; E3 C* F1 \- L3 }( y1 @- X6 L STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
9 R! w* F5 ~! S STDMETHODIMP_(ULONG) AddRef();
" N6 {' s! s7 y: ]! O/ Z STDMETHODIMP_(ULONG) Release();
2 K* U; q$ I3 R; a5 [- [, p7 |5 t) m6 T' a/ m
/ J+ z# l. e( {; n
// implementation
/ W1 J: d* L2 K9 Q) @: q5 {6 kprivate:
( G; ?( b, `8 I8 @) x HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
9 P! ]1 G& J% b) E# k! z HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);3 J6 E' j( O# e* n1 g
6 d( F3 D) n. ` P: p+ b. g# J9 D# g) G$ E. a
private:3 G; ]$ I8 F. s4 A5 j8 x
CUPnPImplWinServ& m_instance;
+ E9 n! g8 M- I LONG m_lRefCount;3 X) v! w0 V% x; ~ O7 l# v
};
# w4 u+ G3 |/ O4 q& S+ I# I _9 @5 [ f4 f) F
( C. v: U9 j' S& r/////////////////////////////////////////////////6 `# H+ X" x: U9 M6 e
+ F+ e) m v% ^9 ^
0 J# h, A+ b( \6 u
使用时只需要使用抽象类的接口。
( }- p. r) A/ w1 G2 eCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.( l" h- ~" H& t6 w% X, d7 u
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
# m$ _$ _; L* V$ }4 \CUPnPImpl::StopAsyncFind停止设备查找.
. S- b2 H! g, Y! q+ b( B* oCUPnPImpl::DeletePorts删除端口映射. |
|