|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
( D: z5 E5 Y* P7 F" s* f7 k
9 F% ~/ _: E+ M
7 n& V0 M. e/ G+ Q; }6 r///////////////////////////////////////////2 b% U5 c1 O' g1 o8 |: T+ p4 M% Z# I
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.. E* m! B0 L+ r! B1 L
( c5 p3 D/ C7 s1 L1 l4 ]: e |, x( Q/ x0 H) U4 i
#pragma once
! L8 d1 Z* j% \#include <exception> o9 v3 J2 d, B3 B. W$ d' P
7 B' u. N! k- D% n4 v; g. _4 v3 W* I" b: Q) w2 _: I& W; f
enum TRISTATE{
: q8 q) ]4 i- _) F- Y TRIS_FALSE,6 t! J8 W8 ^) x o4 o9 \8 b7 p
TRIS_UNKNOWN,* Y6 z7 a8 d' l- j1 o( B, Z
TRIS_TRUE
0 V* H* R |( {};
% H S+ ^" X* }& b' n. |, F' \) [& F/ e8 E$ D
4 l7 _$ x" Z4 i g1 Oenum UPNP_IMPLEMENTATION{
' a& O) w" @1 P9 ]8 h! R% b1 q UPNP_IMPL_WINDOWSERVICE = 0,
9 n: `' C* J4 I S9 V, ?) G2 D UPNP_IMPL_MINIUPNPLIB,1 k: V3 `" v) ?' x+ S- Q
UPNP_IMPL_NONE /*last*/
7 p) ^" o; \3 U) |1 c0 R};* k6 E* K* m7 Y' g# X
0 q( l0 k6 N2 q$ Z, O! N2 z. B3 d
- ]6 u! w* p: B4 d- x, \+ V
" O# {( Y) l! a3 c) ^0 F" I9 l0 m9 s: G, F3 s' E- F! Q
class CUPnPImpl/ U6 \+ d# [$ j
{
. s7 A) A2 d/ ipublic:
& ?& F7 n& v7 ^ CUPnPImpl();, f. R, G, D3 X! {9 \& I4 N# L
virtual ~CUPnPImpl();4 U' u$ D1 a) |( t
struct UPnPError : std::exception {};
0 i# O }6 p* L7 O& |! j' J' c) h enum {
. ^. ^, H5 I( G- j UPNP_OK,
" c$ w0 M* a$ n# C- _ _, M UPNP_FAILED,
, Y8 d( G% F2 @# O6 ]- R UPNP_TIMEOUT. H0 O$ \7 N$ |1 H
};
9 u1 n; ~! S4 I4 {0 t q' X" D2 T* F! ]2 R
2 C/ R9 [% l2 |* f& A
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
* }: `7 D0 y" l0 g virtual bool CheckAndRefresh() = 0;
9 _$ P9 z* t# \, R' P) T virtual void StopAsyncFind() = 0;7 X. u9 y' p: _: O8 C7 C# O5 p/ d+ X
virtual void DeletePorts() = 0;
4 T1 z" N6 q" G- ? virtual bool IsReady() = 0;8 y" E, C1 h: ]9 z% n
virtual int GetImplementationID() = 0;2 J/ v! F/ f) B* E) E1 i! [5 j
: A3 }) K- }! S/ y
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping$ U. ?' G5 Q* b3 t; s+ X t
/ w/ n/ n- n2 c! ?# G! m! u
, ?! ~# m H6 \$ B
void SetMessageOnResult(HWND hWindow, UINT nMessageID);/ @2 _' M# ~6 D5 v6 Z1 g
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }2 m' p; c# n: L1 V
uint16 GetUsedTCPPort() { return m_nTCPPort; }
/ z Q% N( D# s/ b2 ? uint16 GetUsedUDPPort() { return m_nUDPPort; } % }0 o0 m; ]/ e4 ^! B; `
0 Y9 _% @2 w0 d- |% x
0 c0 Z$ S B. l% `( {6 O! ~// Implementation& C3 Q8 s9 `; C
protected:2 O6 _4 e% I6 x3 Y: }" K3 ~
volatile TRISTATE m_bUPnPPortsForwarded;% H# v- t, b7 N1 B$ g3 g
void SendResultMessage();# J# L9 E& n2 N5 @+ ^- w3 `! C7 Y/ P
uint16 m_nUDPPort;; C. E/ |' V8 j/ c) c
uint16 m_nTCPPort;" t6 h* Y/ V* F4 c) h
uint16 m_nTCPWebPort;
- f) ~0 `$ b( T! Q bool m_bCheckAndRefresh;
9 f: T. e ^/ D8 ?% e/ z: {( p Y' n \* `, O6 @
7 l6 ~" X; Q" h
private:
' d! G% }3 z3 J) }; P HWND m_hResultMessageWindow;
- ]9 C1 G2 N2 O' m* J+ N/ g0 n5 [. K UINT m_nResultMessageID;
* v. t W8 }# s8 y) ~" y) e( }! g1 v# K- b
" h0 t# K) G+ [5 ]% ?3 t0 U. P* l
};! e3 m9 d+ I( g& J | z+ d8 w1 ?
c$ q: H' B. [' b6 o9 E0 k4 y3 i4 ]3 v
// Dummy Implementation to be used when no other implementation is available" @: R: |0 ^* W) e$ H/ `
class CUPnPImplNone: public CUPnPImpl
% r: m+ B* X: e% u: ?4 h{
' B* ?; g2 w3 f/ d: qpublic:
. m" n! d% E/ A; _6 e3 F( | virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
3 s+ J$ H" Y6 H0 s$ S+ B virtual bool CheckAndRefresh() { return false; }
4 R4 Q% B# U0 e+ h virtual void StopAsyncFind() { }
* L2 N& U6 i0 j1 k1 X' s' y virtual void DeletePorts() { }
: k2 Y( M- \' E& x2 R virtual bool IsReady() { return false; }8 Y8 x# v2 C# j
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }/ N0 [- h4 u" `
};
, _* w# t" ~% n3 C k" V! c; v9 n- v1 O7 Q1 z0 H# l) l, j
$ F: h2 O; j( x. G/////////////////////////////////////
" ]" G. g* X- T//下面是使用windows操作系统自带的UPNP功能的子类
' P V) N( Q! a1 ~
1 R5 U0 X7 v" ^ e2 ]: w
7 t w$ S H5 A8 o+ Q#pragma once' D7 S! M+ v, C# T; J; f# c
#pragma warning( disable: 4355 ). z/ I$ d2 t& a$ c" i: S1 w
5 b! r" I0 H" ? |- ^
4 w- e4 r' X; U" f: Y4 P! c
#include "UPnPImpl.h"
( w9 b9 C" R- _( z#include <upnp.h>
/ t' d& f$ Z% p/ I#include <iphlpapi.h>
! {& ^' C* i% J0 i" N#include <comdef.h>' z! N, F" V( f; F
#include <winsvc.h># \- k- u$ G+ v+ Z
/ `: C! |% L2 {5 }$ K% g0 n
0 q, D5 A- w2 q#include <vector>: n2 ^1 X3 l' O- j1 G5 `$ ]
#include <exception>
; a1 B2 I" r) q9 z4 T' F" Z#include <functional>+ S* B! Y' [; a/ x: A* I
2 ~0 J3 K- V4 z( k: `2 `# E3 t- \
8 t: i0 k/ r+ Z. ~3 R1 P R" O M4 Q0 g D
) n; |, j' v V' [: k
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
9 n* `4 Z( e U" Y5 Ptypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;7 J# ~: Y/ \; j4 ~
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
}$ y1 T) M) [9 k/ ctypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
/ T8 a* [* K: d+ D ]typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;; U7 k6 X4 B1 ~- X
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
7 d6 k% Y6 i4 W- _; l4 Mtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;- c3 N" {$ W6 e0 w6 M2 }# v
% |( L& r6 Y3 K' \# w2 J# b6 J. O
8 f7 G$ @+ ^+ c+ w2 w3 S8 ?, Ptypedef DWORD (WINAPI* TGetBestInterface) (
3 v6 y0 H: [ L% P9 E( r IPAddr dwDestAddr,
$ G# y6 f7 M6 s2 J PDWORD pdwBestIfIndex2 D2 _; {; |& `+ J! V# ^+ ~) N
);
7 ^4 T! X7 o1 b5 ^. b, `: W* j. M" ?& U- K5 ?
! U' z$ p) x: A1 b1 E) ltypedef DWORD (WINAPI* TGetIpAddrTable) (
$ }2 k( d9 [ n% @7 k3 t8 B. \1 E PMIB_IPADDRTABLE pIpAddrTable,
- O# V# m# C5 S7 n PULONG pdwSize,7 _" i6 @ J' o2 c0 Z9 T; M
BOOL bOrder5 c7 ~7 z% G7 _; h- j
);# O8 `8 S- W {; f
6 X t6 I; L4 a9 r
8 `* G0 x; W7 i* W3 ?typedef DWORD (WINAPI* TGetIfEntry) (
4 U+ _: N; V( p7 N PMIB_IFROW pIfRow
' d& M$ [) P2 u* `+ k- W# p);
" A# r6 v" b! X8 C8 }/ h) H6 o
& R' w; q8 O0 r) A* o& I7 ^
, {- R& D4 C4 |7 Q* a' Z5 rCString translateUPnPResult(HRESULT hr);
# J1 b! U* l& n1 ^/ vHRESULT UPnPMessage(HRESULT hr);" C2 f- E/ s3 n' c5 V0 R
6 T. \% B1 B, d4 B& n2 q/ t7 m9 }- s& r% t/ e
class CUPnPImplWinServ: public CUPnPImpl) \/ p) `3 z/ o% ?! V! ]
{. t7 d) M( ~2 Q% q
friend class CDeviceFinderCallback;
, H* j: {4 L/ j9 N/ _% q0 q friend class CServiceCallback;+ S! z q& d0 P( F8 _/ A6 B
// Construction
) }. e: t+ C( A cpublic:% U6 Z5 z9 ?7 `5 s& L0 v
virtual ~CUPnPImplWinServ();# ~+ a( q. L- P9 i3 o O8 u# K) `4 P
CUPnPImplWinServ();( [8 a' X5 @! E6 P! b4 c4 [6 Y4 H
# ^3 X7 B7 {; \/ I
8 l6 a2 r. n( n* L virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }" x, I, Y) N( \
virtual void StopAsyncFind();
# D7 D/ {* Q+ }/ ~) ]1 h virtual void DeletePorts();
4 H* J( V& W/ L! g& m* V' N3 d5 c! W virtual bool IsReady();, [, u0 n: _) `
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
; Q$ S9 j, \5 w3 M
$ m& `3 I- ]) j0 o9 J6 k- b. p
* ^8 E( Y( k9 o |0 F // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)# k& N! a) M" q8 ~* V7 t
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
" ]* ? `- |, ? T: s" o1 }( l virtual bool CheckAndRefresh() { return false; };$ g/ m. v o6 X- `7 _
% {2 O5 Y, X1 ^9 U0 B/ a: t9 ~. O7 S* D7 T; ^0 @9 f% P0 Z1 ^$ w& ~
protected:
: c/ q, F* g. _' @ void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
- [9 f3 N7 R- L. @; u void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
" U2 X. z D( p) L void RemoveDevice(CComBSTR bsUDN);
6 ^. C, B! G* Y7 r1 k bool OnSearchComplete();
- U p) Z$ C* m: J# L- |& [9 O void Init();
7 }2 @* A% S+ }. K) Q% L: B
& ?& d0 M; O$ Y. W& ?+ B0 `3 d
; _; g: e9 H, J: D5 w \: ^: B: e inline bool IsAsyncFindRunning()
6 b, ~. j! O/ m n {
# R* [ }# [# i6 R if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
8 e. C2 G( Y( C5 N; A {
9 I r# l5 I" F* O+ X m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
& E( |5 F' e: r( q, \/ K+ I3 Z m_bAsyncFindRunning = false;1 j7 g& p' u7 `+ j! L5 W
}
3 ?2 e4 E2 e) O3 T' Q MSG msg;
/ h/ ]1 _/ O5 i2 D; K n/ e while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )5 v6 R; [0 h: b" N5 m
{
1 \4 z, }: b8 r! [8 S2 q TranslateMessage( &msg );
3 u- U7 c* {0 F$ t" s DispatchMessage( &msg );, Y* m9 | ]3 }
}
! h |7 x5 y" K( ?4 Y return m_bAsyncFindRunning;
( f, E; x7 U9 Z$ ]0 w }" X( K" @! S# K2 D7 `( X5 W
0 f; c7 Z, B% |4 e* a
) u+ {" K, c- P! ]4 l4 l7 t% w6 y! [
TRISTATE m_bUPnPDeviceConnected;
, v) T% U. }4 j
. A( I4 e, q& Y/ T1 y g7 R
6 x7 M/ a+ w9 I/ d. s) p// Implementation
9 c- i6 U3 L) a' h // API functions
# z& I/ c( Z- ] SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);$ V" t+ T/ f4 c+ e: o9 l. |
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);( [3 t. {- h, ?
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
: m% f0 q" K" r& Z! f BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
1 Z2 }3 U3 i% P4 _6 ? BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);/ @& J0 |: M( }" }! ]! P
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
; Y+ K( ]- U" l5 `/ t: U# e8 X- p5 x5 @2 E
) P/ F4 q8 h; J4 o' e2 ~% Y TGetBestInterface m_pfGetBestInterface;, @# l. b& G$ P0 ^# ?) n" N$ z
TGetIpAddrTable m_pfGetIpAddrTable;! T k Y `0 G# Z6 j) g. V" d
TGetIfEntry m_pfGetIfEntry;
+ u' X4 |" {6 h* v0 C& t5 `5 n+ K6 T) R2 S" D$ ]5 e1 |+ g9 X! I
2 ^' ?3 }. _& m; c( w$ s static FinderPointer CreateFinderInstance();
. }0 U H1 o! x* g- _, U struct FindDevice : std::unary_function< DevicePointer, bool >
0 H2 L4 V8 v/ a4 Q, x! I3 h {
7 V$ ?" s3 `: m! e6 |. T; t/ T% H& U FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
8 |6 q1 P$ M8 y. D% I result_type operator()(argument_type device) const
q% G# O8 T, A" U9 ?! l" G {' F. ^* ]1 }# y
CComBSTR deviceName;
% N( d6 n) g) c) s; V HRESULT hr = device->get_UniqueDeviceName( &deviceName );/ G9 S, y8 o6 r( X4 ^
4 T4 Z' _5 W, C$ e$ b
6 ~8 @( `) k! N7 ?3 B if ( FAILED( hr ) )7 c1 L% Y% I# p# f" L
return UPnPMessage( hr ), false;, F- ^1 q9 I7 p( R7 f2 s
% v7 N+ y$ j3 n5 w; y& \" E
' A: c; U* v4 J- _- N# {: X return wcscmp( deviceName.m_str, m_udn ) == 0;
( {1 _, _; |7 ^ }) D, ^! a$ V" l. E1 W
CComBSTR m_udn;
3 u O& Y: N+ ~" a };' t. E8 `9 c8 Z& Z
6 ]: e2 y+ j9 z0 Y+ C0 D
void ProcessAsyncFind(CComBSTR bsSearchType);0 R# E0 S; o) [: B/ p
HRESULT GetDeviceServices(DevicePointer pDevice);
7 w) h, J8 R4 ?. O6 M void StartPortMapping();1 ^- E+ r$ [2 r c% Q" Z E
HRESULT MapPort(const ServicePointer& service);! ]0 K- q3 f* m1 s" t5 p6 V
void DeleteExistingPortMappings(ServicePointer pService);9 b1 k' ~$ D0 C: K( M: [+ m( p8 n0 L
void CreatePortMappings(ServicePointer pService);
9 v$ I; @+ s6 v4 S$ H0 { HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
$ d. r3 p( P9 L HRESULT InvokeAction(ServicePointer pService, CComBSTR action, ! U& S4 I& ~: ~" J# K7 C
LPCTSTR pszInArgString, CString& strResult);
) f# U- O' u ]+ D( `& O void StopUPnPService();9 }5 z/ n8 ?; r" ^/ E
_! V+ T. u% T7 s
- N* |8 V ?/ m2 d // Utility functions q& `+ i# D5 a5 S1 C
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);/ _. y$ f2 h4 F7 H7 W# S
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
K! ^' a* Y" j& m1 u INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
. z* d+ Q0 K% [* P void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
& m2 K+ M, q5 N+ H' A% {% P+ m HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);/ p+ u! R8 t9 {5 U/ g$ Q
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
( S4 g, D5 u" z/ f0 c6 F7 ?* y, z CString GetLocalRoutableIP(ServicePointer pService);" ?3 f5 U8 z1 Q+ t
4 Z+ w- K# G9 _9 j* u- s8 Q) G8 O, U/ y5 G. m0 I9 ?: {
// Private members
! t5 h9 H8 D" bprivate:! g& w2 n8 V9 t1 [7 ?+ p
DWORD m_tLastEvent; // When the last event was received?
( h8 A: O7 a. N+ `. H9 I* i. y* h std::vector< DevicePointer > m_pDevices; h9 @* J3 V! f; x7 N7 f
std::vector< ServicePointer > m_pServices;" d! M) q) l- s
FinderPointer m_pDeviceFinder;& `4 S. @& I' `$ y& r0 C: B
DeviceFinderCallback m_pDeviceFinderCallback;
% D- p8 X7 e% ]. x ServiceCallback m_pServiceCallback;6 Y6 }/ t/ J! Q/ M
% f- U; a" O+ m8 a" S1 N. U% v, A7 b* t
LONG m_nAsyncFindHandle;
W- U) p M9 c bool m_bCOM;2 {2 Z& N4 `8 g
bool m_bPortIsFree;
! }# U- j7 Y) ] CString m_sLocalIP;
7 p2 J, X. \) u CString m_sExternalIP;9 M- I) D8 I+ s, P' E) ~1 y
bool m_bADSL; // Is the device ADSL?: C; ^3 t; y& N" k" K! O+ ^/ H$ r
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
( N1 [- @0 ~5 O. ? F$ t# [ bool m_bInited;
" y2 T3 Z0 c# Z/ @ bool m_bAsyncFindRunning;; s/ u: S& o, `' i
HMODULE m_hADVAPI32_DLL;; z( B/ d2 Q: m0 x0 S0 Y# D6 E
HMODULE m_hIPHLPAPI_DLL;1 C: v& V" K9 Z8 c
bool m_bSecondTry;. z) `' c% t" n# M, \
bool m_bServiceStartedByEmule;: }2 t1 T4 g3 k4 u, _
bool m_bDisableWANIPSetup;" a) P- A8 H, |. |
bool m_bDisableWANPPPSetup;% f2 G- N( O* `6 B' ]
% l* } z4 K7 C; z; [9 {
, I! ~4 O1 H" Y3 |1 u, c' Y};
% d# I4 D9 E- P% N7 e0 l( x+ D6 y* r
! u. }6 h+ e. `* K2 F& u5 u; U/ \ A$ T8 s$ \+ W% f1 T
// DeviceFinder Callback
( E* U& B8 x1 P- cclass CDeviceFinderCallback- R- y+ U2 e% l& I
: public IUPnPDeviceFinderCallback
' b# o+ q% Y) J& T! G" u{' M$ L4 c) V. s. F* P
public:* J: X: {/ O' n \. X' |
CDeviceFinderCallback(CUPnPImplWinServ& instance)
; k; v; S3 e" S2 e9 H. E : m_instance( instance )
: {% @6 K( J! ~. q# [/ s9 e+ u { m_lRefCount = 0; }: T% E9 O$ I9 j* U2 j
/ g2 T4 L& ]+ T3 F; C
* C2 D) d2 i5 q* O$ k
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
m9 Y0 p' T( }1 }! B STDMETHODIMP_(ULONG) AddRef();" }3 C v9 P( @% d' i. C
STDMETHODIMP_(ULONG) Release();" s! O* Q, t5 U( S$ S- k* ^
& N1 _8 R( b: _ |5 G. H; e! x: [" v# m* B2 }, Y
// implementation
. P# \7 O2 {. e1 c; W! d. tprivate:
+ k3 U6 d) G% L8 X+ Q, @- y+ A HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);* H2 @/ x7 V' q, E2 t
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
0 {. t- G* m1 Y d2 { HRESULT __stdcall SearchComplete(LONG nFindData);
+ A0 h c; b+ }8 F2 Q! l& L4 {# U" y# @6 |
( K/ v+ K; `+ l( g7 q+ Oprivate:
( A- e) M& x; C) D6 B CUPnPImplWinServ& m_instance;5 B; ^, Y0 x& r6 M, M4 k/ z3 c
LONG m_lRefCount;
# B. S4 V4 G7 n! ^};; O* u( x% w) J. q7 W
Y; x) @7 w1 [0 I$ K4 |! y6 [6 N' F2 f/ F2 ~6 n7 I! U8 ] V
// Service Callback
7 ]$ M% v+ \9 l7 v( J0 ]0 Q& j `class CServiceCallback
" u1 w6 D: x; M* ~+ I1 h1 e2 d* q2 D : public IUPnPServiceCallback
- A1 @" _8 p1 r' W- x{. N2 u/ I* X- s8 t
public:
* p' d# M; \% \" Q CServiceCallback(CUPnPImplWinServ& instance)' ^4 c( m% H! l
: m_instance( instance )
. q7 Z3 X0 z+ @4 S# Q9 b { m_lRefCount = 0; }
1 R! j V! ~+ `' X, M$ R 0 w$ C+ `9 f, s3 s7 d
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);7 `) v& l( C$ ~: D/ o ^# Z6 F; Y1 `
STDMETHODIMP_(ULONG) AddRef();6 X( x& O4 l( g- w4 n/ j. b& f- p
STDMETHODIMP_(ULONG) Release();# @5 A3 i2 W7 h2 Q* G3 D: J4 L
, c7 a1 A) R$ H
( o8 \# b* j: p8 d// implementation
( }- P- h4 ~' T; Z) j6 }3 Rprivate:
5 I# x" v6 l9 E$ u( `" ` HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
2 E( V" z" c u HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);' H0 O4 ^: n7 K2 Q# L. ?
" S& C( k: e* ^
1 |7 Q" n2 h4 R, L1 n+ [private:, C3 v9 r( P1 d$ c8 f, u5 n
CUPnPImplWinServ& m_instance;
9 G2 q- ?% m8 q LONG m_lRefCount;7 @5 i1 Q3 J6 y' Q1 P* q
};
9 s- ~9 B3 D/ P/ T3 ]! ]$ ] s# H7 Q# t3 { e
- p$ f0 G* ~# u7 W( _5 v/////////////////////////////////////////////////3 G& F5 [9 h: B8 }7 w- h1 d b
: N. z/ f! R5 v. U) D& x5 d" L( H5 v& y/ x
使用时只需要使用抽象类的接口。
9 \9 U& v# g: Q" G1 wCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID., T; `% u7 I4 a, U k) X$ E2 \! R( [
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
8 w0 g) [ O9 i2 yCUPnPImpl::StopAsyncFind停止设备查找.
) |5 R3 S/ D7 ACUPnPImpl::DeletePorts删除端口映射. |
|