|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,* \% `6 H7 a5 o* K" W
/ q- N0 O9 `; i& F$ I8 @8 B! m6 l/ b
///////////////////////////////////////////
4 ?/ F7 B j6 y# [//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.: L. J2 m1 W" S2 ^
! v9 j' E9 H7 A" o% |: P' @) a) r: u+ m* d* S# p
#pragma once2 |% K" e$ n' G
#include <exception>
) n8 ~0 |" ]) p! w! G& H8 R N( }
+ f7 y2 @3 Q9 ~ m4 ]# m enum TRISTATE{
6 _! d8 e1 K. E. {3 c8 e TRIS_FALSE,: B" N$ ~, W( G" ^8 m- }
TRIS_UNKNOWN,
6 O) n- b3 i$ T+ h TRIS_TRUE) t3 p# ]7 O, O$ c% w! w
};; _4 x3 T+ r7 A# i9 s% _; K
* j0 x, k% X n7 G) ?
# m7 E. f& G% p+ ~8 w7 G& z, j; Yenum UPNP_IMPLEMENTATION{9 x. h# y2 E* H- }/ ]
UPNP_IMPL_WINDOWSERVICE = 0,
0 B1 d0 G. A. y$ u+ B UPNP_IMPL_MINIUPNPLIB,
# z7 g- a1 {3 Z1 U( G* r) Y UPNP_IMPL_NONE /*last*/
1 O8 d; g/ L$ k9 r4 `, K p};
, `4 V" X+ W$ V; b) f, q ]
: @# a" w7 b0 G; M+ b6 ~3 l, F- L+ M" m! w; \
. U' W! s" a* n! u9 t% N4 E' X
( h. q3 X( b2 B% H8 Z4 x$ D& I9 M2 T
class CUPnPImpl- G$ ]) n; ?0 }
{
4 a/ S/ I2 l& h7 W5 c. Epublic:: }0 X8 x% {% U: S/ u% x
CUPnPImpl();% e. P" |: m" L* f8 g" Z9 Z8 A
virtual ~CUPnPImpl();
2 Y5 \5 G! x9 i& o! o2 m struct UPnPError : std::exception {};* O0 O( C7 \7 D n5 a
enum {
2 I7 [" _- n* Y6 v9 I+ V UPNP_OK,
; u) o$ e4 m2 k% I+ [ UPNP_FAILED,
7 j/ E4 B% {- w0 u3 ]2 C3 p( ` UPNP_TIMEOUT! s% K( W' d( J
};
! E2 S2 L+ y( D) Q, a% L: {- @% K. |# @
2 W5 J/ _1 E/ o: I2 t virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
. w# a0 q6 d1 k7 ?5 d virtual bool CheckAndRefresh() = 0;
( J! j1 S# q5 i8 T+ V* o- q virtual void StopAsyncFind() = 0;
% r; N5 G! ~- ]( Q9 b virtual void DeletePorts() = 0;7 V! o9 @+ Z5 G( O% E. J- y
virtual bool IsReady() = 0;
J% f, @" O, O4 t! X( s. _ @ virtual int GetImplementationID() = 0;- j8 Q9 X' W m
5 N; p5 Q2 c0 ^. j/ N- T8 _
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
# I: \1 L6 j% f& Y; j; B3 g' Z$ b
6 T9 A6 t4 k) N! J: E& t5 B' k1 x/ z8 H7 L- Y% N1 G
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
@+ I4 S9 Q0 x6 l' `/ h TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
0 J! J5 q% ^/ i$ [) i uint16 GetUsedTCPPort() { return m_nTCPPort; }( G: i8 a& G! i+ @7 _/ d
uint16 GetUsedUDPPort() { return m_nUDPPort; }
% J1 Y( k$ j9 Q/ [6 G# k7 j; L' O4 n; a- e( |2 |7 g" {9 A
1 O% o) }) B0 i$ b// Implementation
% b7 V# B" _! ]) ~8 Z4 {" D8 pprotected:
$ s2 E5 I" W) m# }3 l5 I volatile TRISTATE m_bUPnPPortsForwarded;# N9 s* G& l- u
void SendResultMessage();% ?( n m7 \; l5 B C
uint16 m_nUDPPort;6 i6 _# u5 b9 E8 a* ~' u
uint16 m_nTCPPort; a8 S$ u- v" }
uint16 m_nTCPWebPort;
. r& d* Y1 X) J% z1 }7 i0 [ bool m_bCheckAndRefresh;
; m1 N( Q( V% f! @5 S1 F* s$ M" ^) r/ U, ^6 @' u6 H3 ~3 k
' U7 }9 Z$ A* T+ K
private:
, e' @! G3 n( h HWND m_hResultMessageWindow;
( o! I+ w! d) S6 @; _6 o UINT m_nResultMessageID;- p, ~9 }4 t; ^0 |& \1 m
: v$ |* i( g( G/ Y ~ T
, A4 p. W7 K. I; l2 V. V3 U2 w};# F: [) c1 d" b: |! b l
8 r9 a% g- }2 j* k8 a* V
+ ~; _4 i1 u7 Y# S6 }: I3 h: L// Dummy Implementation to be used when no other implementation is available
; n3 ]( L2 G" r& B0 j3 M# |4 G( jclass CUPnPImplNone: public CUPnPImpl
3 o% S2 B4 ^# s, @/ P{* k' h! q; x6 c& T6 d$ e
public:; C+ r3 }. p& c/ k
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
3 {: T+ G( C2 ~ L virtual bool CheckAndRefresh() { return false; }3 {1 S+ C C6 _3 n
virtual void StopAsyncFind() { }2 i- q( S7 E0 a' }
virtual void DeletePorts() { }) C7 v9 |6 Q0 }% r1 d
virtual bool IsReady() { return false; }
- M* N6 O9 ]- o: Z2 I7 W3 } virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
, |' _" h& I* H, G};
( |8 K% Z. e2 O2 ]. @9 d" D2 F! T
) {3 V. l9 F- D4 f3 v* j5 _0 O# y3 T4 j# c/ u
////////////////////////////////////// H8 p7 b1 x) }
//下面是使用windows操作系统自带的UPNP功能的子类
/ K( l5 x; Y# \3 a9 B
8 Y x6 C5 I, r/ Z& ^
* T& V. b2 A2 N5 J- D' T. r5 v4 Z#pragma once
) U- _/ {3 j; Z* D#pragma warning( disable: 4355 )2 |) q9 e, I8 c: R1 j
Z- C. b5 A6 a9 N1 ?6 ~
6 y1 Z7 D; Z) E
#include "UPnPImpl.h"% s. Q, ?, y/ l
#include <upnp.h>0 i. L& I' n; u
#include <iphlpapi.h>
7 ] p7 P% p! @#include <comdef.h>% n# o; h3 c/ t3 |2 r* D# j
#include <winsvc.h>
, m% ?( J W; ]0 i5 `
5 j @" \5 W! G9 i: j) x4 n7 C! J9 [1 X* G5 l3 G
#include <vector>$ W! E4 Z5 n/ h; z/ f. f, Z$ A$ F" p
#include <exception>
# e1 k* O) J5 T; f2 j#include <functional>
8 A7 i4 j& M7 u+ t
; D/ T8 a3 j7 v- P
. b* n- m( L9 A. U5 L: f- f8 g4 X! `9 {5 c
' G" A/ a& R3 s0 ]2 k$ q6 x2 ^typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;+ t) Z* k% N, y; Y
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;# x5 f/ g- d$ J: r* r& S
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
( m, A5 r, A) S( M. Ctypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;5 z: K0 D* h8 h& _2 S
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
7 \/ c. ~! j0 {5 s3 xtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
8 \' g+ n6 c5 `) e8 s: G; btypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;) u6 |* f& ?+ B; T, i% c6 A
4 S& W: W# R8 p# W" e* `* W5 x. f. m6 `
typedef DWORD (WINAPI* TGetBestInterface) (
8 K$ t) Q( U: x0 T( q IPAddr dwDestAddr,. Z; y+ f1 q8 J& N2 k: W6 f
PDWORD pdwBestIfIndex: h0 h- ~0 q$ T8 O5 |& ]. G
);0 W" Z: e+ ?6 J3 L# z1 ~1 [
* u) w+ t# l: Q
5 X9 a! D- S6 }' k( Ttypedef DWORD (WINAPI* TGetIpAddrTable) (
, _* Y# m8 r. }- I/ K PMIB_IPADDRTABLE pIpAddrTable,
5 m, a# T. V- Y PULONG pdwSize,
# d5 S4 q( ^3 N8 w# [ BOOL bOrder
8 Y% Q1 e# Y( L, M);; a6 w) D0 ]% ]5 ~: _; @, b
. c8 {1 K" @2 p4 X, [0 O, S/ E1 {1 h
9 M7 R" m$ `' Xtypedef DWORD (WINAPI* TGetIfEntry) (: p; p; @* j" Q' [' r2 e
PMIB_IFROW pIfRow0 w- r' L# ^; q7 Q
);$ J5 K+ N0 c; n) K
" W, V, r+ g2 S% }
0 O& K; r$ a' ~CString translateUPnPResult(HRESULT hr);& N% O. M5 r u; P G
HRESULT UPnPMessage(HRESULT hr);0 }/ i# c g6 x9 P/ _2 S& {
; X3 v7 B N" H. r# D" c. a! m4 V7 e: ]
class CUPnPImplWinServ: public CUPnPImpl: x, Z* u2 G1 L& {; M6 j9 Y
{* J+ B3 T- {* y
friend class CDeviceFinderCallback;/ b, [: a- B2 y1 M) z0 R) I
friend class CServiceCallback;
8 W1 o2 t, {2 r// Construction" r0 M: u5 {) f- ?
public:4 e4 M+ z' I- n3 c- E1 N j6 t
virtual ~CUPnPImplWinServ();6 @' X* `$ H) w, U) T H1 W# X
CUPnPImplWinServ();/ t/ U! r1 a! x( q; x
, O+ M. O0 h$ K2 `3 Q8 Q% C5 I9 R4 G0 h- z/ A# r" @
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
& c j3 P0 E* { virtual void StopAsyncFind();
! m, d. D5 N" {6 o/ y9 k5 g3 S8 X virtual void DeletePorts();5 a* ?+ n; R9 _$ ]
virtual bool IsReady();
( q% d& I" x: |4 o* b t9 \, G) A virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }: k! w) _: `8 z! F& z h$ G! W
9 m5 t% ~; j& I6 c. z0 ]7 m: ` ^8 ], r9 ]2 {
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)* z9 D b( l K( p" J2 E5 w2 \/ V
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
& L! \% e) o2 o& Z! U5 U virtual bool CheckAndRefresh() { return false; };
, g/ s4 W4 p5 G& }9 Y' b+ T/ R! `' Z$ V# H
2 }4 R( V. V- A- e' b2 z
protected:
6 X! Q: |/ M- G void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
" a! R/ |0 e. `! h$ B, d9 c void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);6 T. v$ G& U) L8 F1 y
void RemoveDevice(CComBSTR bsUDN);
" R( O9 c7 a3 S- C1 v6 d bool OnSearchComplete();; p6 z/ m! }: t
void Init();
, e% G8 O. ]% {) z2 d* I& j
0 u3 E- q+ C# x# k( s8 `5 P
9 m2 T) u7 n; y! s inline bool IsAsyncFindRunning() , g7 \, \* ~# s( C" {) ^
{
$ l1 k( ^! R# g if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )7 m) X! V- `/ r5 V. k I8 {
{- I1 Z; N! K! e* _
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );! ?3 T+ D; o* o6 t E
m_bAsyncFindRunning = false;
. A o9 w6 X2 \ }$ b. A) l+ _* V/ X7 @
MSG msg;
- M& u: t8 s0 p/ ]0 W while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )$ I7 v9 t9 @; h: R+ {
{$ A6 g) v# f/ Z- A4 ]' D
TranslateMessage( &msg );
; ]' i" J. m9 l5 b( f) A5 R! { DispatchMessage( &msg );! \. K. h% A( E
}
4 G1 C' f9 F; o% M; {6 _0 d return m_bAsyncFindRunning;+ u$ ~$ U/ N0 Z' x @
}
4 [9 A: Q m$ g) c( s0 A6 g+ r# [7 X
+ v- I: H" s+ e2 W4 U. ] TRISTATE m_bUPnPDeviceConnected;& B1 v' r: t: k* P( S9 M+ o
; z) g" q" V! P! }
r$ r4 ]$ p; a4 {/ K// Implementation$ R' m2 s7 p! Z0 [: G7 [( x5 `
// API functions0 b: N8 [% {" v
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);+ u x! B8 f1 I
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);6 a" U3 G/ u q3 f7 b; c7 T! z* T' i
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
5 ^0 K) s; `/ N. H# B3 O BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);* ^7 C9 ]9 Q; y7 z
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
7 X. @! r" }1 f) N/ Y BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
/ i& v% @5 f5 E) n) ?6 o" ?& ~
2 d- l$ s3 m" c0 l( ~5 v
+ [! }" W# ^ B; k$ K1 D9 l. | TGetBestInterface m_pfGetBestInterface;& Z ^& Z) x" s/ V
TGetIpAddrTable m_pfGetIpAddrTable;
( \0 F+ f" R0 ^. H3 J! w TGetIfEntry m_pfGetIfEntry;$ Y* ]% X2 i# z
6 U0 e: \# G8 [ A2 C- L
1 a3 t2 _8 @' s8 B static FinderPointer CreateFinderInstance();# Q9 w9 h/ A- a3 a' t! Z
struct FindDevice : std::unary_function< DevicePointer, bool >& k$ P1 l- E! L- h/ K C. A! _
{
! ]' p+ o( G3 F" [ FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
1 T8 Y3 N$ x: f$ m4 S9 F result_type operator()(argument_type device) const
- T( u9 e( {4 w8 `9 { {# `3 A( T, f3 X& U# C9 a
CComBSTR deviceName;2 D4 W3 b* ~4 B! P7 [- P
HRESULT hr = device->get_UniqueDeviceName( &deviceName );* K/ z" N( H" m. A# T8 s+ x
- }# d- @: z# K
2 F$ u( {" {. v, }( Y; O if ( FAILED( hr ) )5 T! y* v" W- w1 l. b5 L9 N
return UPnPMessage( hr ), false;
9 s, l `. ?3 e( D, ~6 n
# E3 V- A4 A, l5 h: S1 z3 a5 Y- N2 \5 a# F* y
return wcscmp( deviceName.m_str, m_udn ) == 0;+ ?" \7 E. ^7 Z; L! u$ K6 G
}. h ]7 F( q- F+ |2 u+ A
CComBSTR m_udn;
7 o; A+ [7 a/ N) s };
; e+ R# ]# ?& a . ?$ h: M3 @/ f8 w# ~4 [
void ProcessAsyncFind(CComBSTR bsSearchType);7 }3 Q" H. A& {! P! v
HRESULT GetDeviceServices(DevicePointer pDevice);
) l6 v! M+ \+ x3 A7 L, T7 f void StartPortMapping();
9 Y6 J: r2 ]' W, z. Y0 w8 B9 v3 t HRESULT MapPort(const ServicePointer& service);+ f+ a$ d, E8 q$ G9 \
void DeleteExistingPortMappings(ServicePointer pService);# j- U: n4 p C5 J7 l
void CreatePortMappings(ServicePointer pService);
) [4 ?9 L6 m: ^( j& T HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);$ Z& A: `- b d2 ~) {* T
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
% z4 S" z8 d/ A8 y5 i! R LPCTSTR pszInArgString, CString& strResult);0 G" \% Y$ d+ q5 _* p3 K
void StopUPnPService();# ^/ A/ u v7 x6 _
6 e- k u8 O! l! k- {
" X" p: A) e$ w7 u+ } // Utility functions
# n7 ~9 A7 k9 O# I$ i HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);5 z; o' l* |! Z9 h& f
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
4 a: T A7 ^8 C6 X INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
5 d: {0 F* r! g; g void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
* n/ [2 T/ ]/ \6 N) ]$ A T HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);0 q- ]0 o p" z* K9 }' u/ ~5 Q
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
; Q4 Y y4 b3 ~; \ CString GetLocalRoutableIP(ServicePointer pService);7 G$ V1 {8 e Z/ r
8 g* w+ R7 [7 Z) x# N) |" A4 U$ A# \
; p# k8 k& i" r( {6 t3 t// Private members" B; R3 R9 A8 x _4 m
private:
. U4 E3 O {+ M5 v X3 u DWORD m_tLastEvent; // When the last event was received?
6 `9 `7 l1 E/ f( H* C/ r std::vector< DevicePointer > m_pDevices;+ B* d0 }; Z; E8 `1 {
std::vector< ServicePointer > m_pServices;, J4 g) w1 Q% f# ~
FinderPointer m_pDeviceFinder;. g$ U$ |( M2 P- r M
DeviceFinderCallback m_pDeviceFinderCallback;
8 S2 k7 y- W: j3 d ServiceCallback m_pServiceCallback;
4 U6 O9 o) F' W7 z) I
+ G- b' u8 O, v7 ~
6 q* [! P1 B- M* j5 L LONG m_nAsyncFindHandle;
! K% ~! V3 z1 e9 s bool m_bCOM;; v# h2 V# F. z
bool m_bPortIsFree;
" n: [1 D. X$ w2 \! Z CString m_sLocalIP;, k$ v0 s" ~) c
CString m_sExternalIP;
% D5 C, [: }3 b0 z, w q) v bool m_bADSL; // Is the device ADSL?$ {" K0 P/ e. k- a
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?5 M8 \8 B; u/ x8 U
bool m_bInited;
; v0 K: }% d1 s/ b" u bool m_bAsyncFindRunning;5 |! _* G0 g+ G: V5 @+ j) t4 {' B
HMODULE m_hADVAPI32_DLL;
4 E, w0 F' u' ]6 x, G& b; K HMODULE m_hIPHLPAPI_DLL;/ }& j0 _: g; A8 r6 r+ f$ C
bool m_bSecondTry;0 P5 f" g7 a/ j, ^
bool m_bServiceStartedByEmule;. i9 p% j% B3 m- I& R
bool m_bDisableWANIPSetup;5 L9 |$ J e' {4 C( R
bool m_bDisableWANPPPSetup;
) S# R, q& W" ]4 W& H
% x; m+ c% B- j: W2 V. E& c, b% o Y6 @( _* ~- H
};" r' o& R4 v& P8 i
6 y N6 k& k' G, V- a: \. _% h; E6 M: I( C2 R
// DeviceFinder Callback3 _- o2 @! x, n7 e
class CDeviceFinderCallback ^! R9 C, q* r: L
: public IUPnPDeviceFinderCallback( t( r9 u& y! W+ k# A- s7 u# s! y
{' Q& Y: N' {- f# k; p( u+ H* P5 s3 R
public:
/ O, S9 D. d8 O) X0 n CDeviceFinderCallback(CUPnPImplWinServ& instance)
- G! b0 m0 S' @0 c. j- m! ^ : m_instance( instance )/ ~* F4 S$ I9 r6 k! x7 p- d% B
{ m_lRefCount = 0; }
0 ^( ~2 p6 O: `7 i9 r4 b, x
5 {9 Z5 o7 g, D7 r F1 O% d1 O( ?8 s" O, S: R) R/ _& d
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
+ ~+ P: ^( [: i7 f3 J/ [8 ~ STDMETHODIMP_(ULONG) AddRef();1 @5 F U3 X) h, o
STDMETHODIMP_(ULONG) Release();
- a" ?* ]1 A" [$ r7 C, b l) C
8 ~6 `$ e9 ^: w" S7 m# @6 n/ m* }1 z! B; N; Z$ X& Y |
// implementation
: ^( \! c3 ~5 L0 Sprivate:' I9 A1 S' h$ p, W+ {5 h. l
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);' c; Y- |6 b7 x& e3 n* p
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
/ m7 C" Y {6 ]# A- M1 ~! L HRESULT __stdcall SearchComplete(LONG nFindData);# ]: o/ v! j* N" ^$ t( {
: I& W' b2 q' h$ z+ F+ M/ Z6 v: Q' V! l4 t# \4 {, P; [7 p- q! ~ W
private:# g6 s5 R. m" ?1 U0 Z" z
CUPnPImplWinServ& m_instance;$ c/ u1 a T+ q8 w% l1 b
LONG m_lRefCount;5 [& i/ [: E$ m
};( U( I& |, U( w' c* i& P
; O4 m- ^( n/ `) n- n- e1 N, e
5 z6 w" e- H5 A( b# n" C0 T// Service Callback
8 T) e- G5 b, P. F; Gclass CServiceCallback0 k/ g8 E/ M Y! O; a7 w8 W
: public IUPnPServiceCallback' p& D: }7 w' \. S; T+ {; K
{2 K- v/ l5 T0 f# X( g; I
public:$ u: \* u' L5 K: U% k# @- e! s/ v
CServiceCallback(CUPnPImplWinServ& instance)
/ i3 `) I1 l5 k% O3 h : m_instance( instance )) l, N4 `" v7 _# b+ T5 A
{ m_lRefCount = 0; } d4 I9 O5 v1 m5 A( ~% f8 V
# g! i r* N$ D6 t! o STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
# P9 ?+ @* q' G% n4 D STDMETHODIMP_(ULONG) AddRef();
0 E2 a; z& j1 b STDMETHODIMP_(ULONG) Release();- y W5 z1 N& m" R5 e# r$ S( B
Y. u" A! q0 b1 Y& l) W& z ]5 }# q# M0 b+ s5 ^
// implementation
8 z6 ]2 h, S, gprivate:
( l2 |/ ?+ X" ` S: N& o' b' f HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
! v% X! [# W: h* z' w" {1 v HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);, a% d) O( M [0 t
6 Y) D9 r8 q1 k( P. y* w! f! G2 ~0 b3 c [4 P' t, o5 \
private:' h* M% R" J0 Z+ M1 Y% O! ]% e
CUPnPImplWinServ& m_instance;0 g. G2 D" E- [+ p1 O# z7 u) i
LONG m_lRefCount;
1 W, D; ~' P/ S; P. k};1 o( W* I. ~; Y, |. N D& P
1 U% J, q, j* _+ X. U
5 u$ f; D f4 ]" N
/////////////////////////////////////////////////
' R* Q1 ^7 i! ~! h9 S5 ~6 C8 s; b& I7 w! U( K
- [! r/ }; r" T
使用时只需要使用抽象类的接口。9 @' @, w1 T4 A" Z! a/ ?3 I
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.) D+ [ B! u, R g
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.; a% J9 {# n1 i8 `. C: R/ d9 h
CUPnPImpl::StopAsyncFind停止设备查找.- z) w: y' {( t+ \
CUPnPImpl::DeletePorts删除端口映射. |
|