|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,! {. Q f9 ?" v6 h0 @/ r H
6 I8 A( M# S" z6 W2 G) f
' r. p7 G/ J' ^4 O7 v///////////////////////////////////////////& A- }+ F \- m# Y, }
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能." S R- x6 f6 @9 \ A& A! d" w
3 H! j$ a% T/ c+ H' K6 I5 b" s+ h. u9 G' s: S1 G7 c
#pragma once: w% B0 D$ g! T& L) u9 E
#include <exception>9 ~: v% t: I) U& V9 U
. L' _4 Q" E1 x$ s
% h7 z9 g, P4 z# ?% ` enum TRISTATE{
* o7 d/ V1 L& g4 ?: K+ Y' s; g8 H TRIS_FALSE,
H3 t1 N; h( W TRIS_UNKNOWN,3 M) m9 L7 N! J! m. v6 [% \
TRIS_TRUE
5 I9 S: w4 q0 e1 p};
; z9 M- X' d3 C5 n5 Z9 T( D+ ?- e, P( A4 m* }5 r y
! @9 _* B% I- p$ ?
enum UPNP_IMPLEMENTATION{
6 u% h4 I+ b4 N. y) D7 @' d8 `( f UPNP_IMPL_WINDOWSERVICE = 0,+ g n6 G# N9 F6 j8 k' ]6 _) ~. H; [
UPNP_IMPL_MINIUPNPLIB,
4 A5 ]$ p# f1 T UPNP_IMPL_NONE /*last*/
/ b, F# z- Z% ]0 O. F2 D7 b$ ?6 M};& @. h N1 @% X. E
' I/ P7 L- S9 q; s4 g7 R& Z: _: J. w/ U) I) Y9 J; u: h
. S3 c! q9 J9 H/ t7 X
- I6 n' s7 c5 p
class CUPnPImpl
# d' ^% a+ `, I0 z: t; K{
( W/ ^7 A$ {2 C2 fpublic:, @5 M L9 p4 j
CUPnPImpl();
; z6 n1 p* v2 Y; t virtual ~CUPnPImpl();
1 C4 T' i, P1 @9 I ^ struct UPnPError : std::exception {};
) K s |" k L+ O/ i8 q# I enum {
% f8 n$ e5 G8 M$ O% X UPNP_OK,& ]: C' h- x6 i
UPNP_FAILED,5 j1 M! ~0 K) A& r$ O$ I1 `7 t7 a
UPNP_TIMEOUT
8 b; t# J1 w, _ };& m+ Z: O% E+ |; g) |( ~
& P/ }2 O8 A! M o# s) o4 k& I# r4 p; ?$ V3 A! U W7 _/ c* ?
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;; _7 j, z4 G2 A n n/ @* o
virtual bool CheckAndRefresh() = 0;: v+ `6 l. n- L) Z- l0 V4 z1 O9 ]
virtual void StopAsyncFind() = 0;8 }, o4 w! t! V+ E% R
virtual void DeletePorts() = 0;
5 H, m$ \6 c! S$ J P* N5 T virtual bool IsReady() = 0;% w% B/ q3 B1 B4 Y, z! l5 l* G
virtual int GetImplementationID() = 0;* e7 Z4 M% `( U$ h+ N
4 o( ?2 x5 Z v1 c8 e, ]( p; C void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
2 ?4 f" [; i$ Q$ t8 O" N9 ^1 J2 G& K8 i7 |0 J; Q$ n
/ X) j! A+ y2 Q8 H/ m8 r
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
! s( U% f9 G9 c& e/ e$ x TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }8 V# c5 J3 [7 V: h
uint16 GetUsedTCPPort() { return m_nTCPPort; }' _4 B. \2 T& [$ @% h
uint16 GetUsedUDPPort() { return m_nUDPPort; }
6 }* D* V& g9 l' u( W$ T% [( B# U; u- P! \& N1 p* w
$ j; I, ^$ B9 a. |# G2 w5 P$ ]' e// Implementation
$ B4 D1 p% k' H G1 L' G) Vprotected:
8 Y: [; E' Q* A5 e volatile TRISTATE m_bUPnPPortsForwarded;
3 E3 o5 d! _6 F/ T* q8 U+ A/ \ void SendResultMessage();' n+ }' }4 |$ `: ~3 H1 X
uint16 m_nUDPPort;
6 ?- [6 R/ s8 p) }5 C( b& g2 [ uint16 m_nTCPPort; ~0 v) O6 ?! }2 i! E
uint16 m_nTCPWebPort;, F6 x' L5 c& Y: d' D# q
bool m_bCheckAndRefresh;
1 |' w( a' ^; {0 }, A- p
6 q2 f) V# F% |: ~$ o
8 p% _% o" {+ b4 Dprivate:
& [; j" s1 X% B2 q HWND m_hResultMessageWindow;# w3 ~$ k$ W( p+ K3 @8 p0 f
UINT m_nResultMessageID;
5 U; D6 f" `5 x$ }" U' h, ~$ ]+ K8 T2 A: S' d
/ n. z$ c4 G( o4 V6 C};
$ F9 K5 G) l8 S6 ~7 D+ u. K' K$ ~8 k) p$ ?' g
) k1 ]' w6 d" w: [: `* a9 d
// Dummy Implementation to be used when no other implementation is available
/ g3 d3 O# n: c+ j5 o& Q6 _2 {class CUPnPImplNone: public CUPnPImpl
3 Y& S, C* [; ^4 [% `{
7 n# [. z0 W1 n% q! hpublic:3 j- k5 d5 S$ I5 k/ c! {
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }. l, B4 B; `5 Z3 s$ d
virtual bool CheckAndRefresh() { return false; }
7 J1 ]2 B" l* K. D$ r virtual void StopAsyncFind() { }
* f; ^: A" B' d" m3 B$ e" R" W* L virtual void DeletePorts() { }
% ^* m! |7 ~5 {1 A. f virtual bool IsReady() { return false; }# v8 K" k" a6 z% r8 z2 s
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }7 ?& p+ _9 q8 S0 z# s2 f
};
! N% T- G( D3 a( I7 b
! W. A" a) y0 I8 b9 q- l8 k. |; n* W) |5 {. w0 N( ^
/////////////////////////////////////
/ p3 r% h* e4 T5 y% A//下面是使用windows操作系统自带的UPNP功能的子类9 v$ s- s5 P& o/ K4 ^9 a
0 u, x d. y5 m- q( [
4 P* Z' T& h; S: }. G5 @( z- L
#pragma once
% q1 `, N6 [; ^5 V# H9 t3 s#pragma warning( disable: 4355 )
% e L! g2 \7 a6 ` c9 ~/ O$ d9 B* U7 C$ F" c1 c
# t9 J8 ]- i" H) c% s* R
#include "UPnPImpl.h"6 [1 O; |, A* V
#include <upnp.h>; j Q" p! A2 [: N/ H9 ^- F
#include <iphlpapi.h>
i* X7 F5 T7 a5 Q, i# f#include <comdef.h>: ]7 K& W$ S! w" P! Q' S, S
#include <winsvc.h>9 U4 B/ e+ U& S% g4 F; H
( ~( {4 M5 c ?+ \; w. d7 p
9 i! h: L3 n# W4 ~
#include <vector>
7 u: {, b9 ]: X2 e" `" U0 T, i#include <exception>3 \; }" M: w/ Y# }
#include <functional>
" i$ h7 z+ r7 _7 Y: Q" m5 P' z5 E( u) `3 ~- c; ?. x4 ~: _. ]
( P8 w. [/ u/ V" g$ g
1 Y! Z. M0 F' s- p3 J+ P$ }/ b2 {$ H1 T, r5 s# }
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
- b! }6 s/ M4 s7 _6 u( [+ atypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;1 `( y$ ]# X' l2 o+ ]# B
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;9 ~: L! X) r. A4 s
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;% ?3 l# T x/ k# m. i! }9 z
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
$ ~. y* z" d+ y# M- T% D6 G/ T. ^typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr; J* W7 M/ ~ q
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;+ }- J" k. n9 h" g( ^2 ]
4 S s9 M# [' X" B E8 T- `# `' G2 m w2 |
typedef DWORD (WINAPI* TGetBestInterface) (# _4 x2 t9 e. {0 a( z: Z
IPAddr dwDestAddr,$ s4 P# U& a! }% X# }+ G$ v u
PDWORD pdwBestIfIndex
* a1 Z5 T2 P% [' A# V7 s* y0 b);
4 m6 p% h4 o& P, a; N; v$ P* ~: i
% D& o8 M/ }' T+ x& a
typedef DWORD (WINAPI* TGetIpAddrTable) (9 p' ?8 A. |# B$ K$ ^, T: d
PMIB_IPADDRTABLE pIpAddrTable,
! W2 V7 P9 m/ L0 `* O( e; y- Y7 T# t PULONG pdwSize,
: F" }7 K- n, x BOOL bOrder2 a/ u8 L2 p9 g' k
);
, B- d9 s9 |6 `$ C6 X$ D. \$ {
6 ]: f6 i* f: W( i' [- ?; f7 x" M6 [0 }5 T
typedef DWORD (WINAPI* TGetIfEntry) (
$ k3 t, A/ @9 l6 \7 u9 @- O; y PMIB_IFROW pIfRow: d, h! F8 G. y
);
0 V8 w+ x: _/ q- g# }. r8 \) j8 g% O6 G) f
# W9 P% M" ]* x6 a2 mCString translateUPnPResult(HRESULT hr);
9 n0 t& t& ~/ D, ?! ? uHRESULT UPnPMessage(HRESULT hr);( r$ I: ?& \/ [& r, O* P
! V) U+ Q1 T! N7 Y
5 n. R- S( ^1 Kclass CUPnPImplWinServ: public CUPnPImpl
/ u' P! ]. u: O# K{
9 R; z8 n, m6 i7 x( p friend class CDeviceFinderCallback;( [% T8 I H+ _1 Z( |
friend class CServiceCallback;4 ~) c/ p9 F; J) C7 K2 e
// Construction3 c8 x4 y6 q, W5 L' M; S; b
public:8 [6 a9 b" W2 k3 S
virtual ~CUPnPImplWinServ();
6 _9 |4 Z4 ?- Q9 Z+ p CUPnPImplWinServ();
, N; j8 W# J' J, F
3 ]3 \6 T2 Y2 U2 g; Q+ u. F5 c3 J2 h" w' q# ?. q. w: }/ U6 Q- V
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }; ?8 ]$ l7 `; Z, o# C3 f
virtual void StopAsyncFind();
F |" H7 f( ~- Z% e6 s virtual void DeletePorts();- b' S# Y5 X% c$ L+ S, F$ a
virtual bool IsReady();
: i' T* Q! C* B: v$ H( S virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }5 C# y, b& W1 N5 e# M$ s9 n
" Y6 T% {/ U$ }- Z( N% w# ?
4 I0 \+ b, B+ _# A d! F& O // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)- c! s+ ?% g9 k' P5 C
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later- ^9 n7 T: H0 v* J6 o" t1 W$ a! A
virtual bool CheckAndRefresh() { return false; };
5 P) y4 S% ^9 Q( P/ ?5 C# Z3 f! g: P" c; U
% W+ g5 p9 d# M8 C, Z+ P
protected:
3 h8 B# _$ c" l. Y void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);2 G1 n% }5 o$ F6 n3 O, _
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
; W# U! I3 V+ c' ~+ w6 |1 B void RemoveDevice(CComBSTR bsUDN);
( n* |* n& _0 ]& x, b2 a1 ^" ~ bool OnSearchComplete();+ x2 i. s9 u9 d+ V' z
void Init();3 r0 T' O" Z. O# A; r: V2 ~
: w, V) o$ b1 b4 Z
7 {! G& i$ F( c4 t/ \ inline bool IsAsyncFindRunning()
0 t6 W4 L# X" e- C {
' I2 o$ e$ ~/ v- G x _4 u if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
4 P6 e4 T! @ w; l" ]- K; x. K {3 R) q( t. K! y" f1 z
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );6 I9 H3 e" a) d* `4 D8 N
m_bAsyncFindRunning = false;
* L0 g8 w, @; |' [. q }
+ B* h7 u s: j9 u MSG msg;$ m! {0 T1 z" y& M6 Z
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )8 B" w. Z; _, E& U- v
{- z2 p, Z9 u5 D) N
TranslateMessage( &msg );3 }+ _8 l6 s8 f" ?, r
DispatchMessage( &msg );9 `, M/ x3 P' J; Z0 m3 L
} E4 Y8 x% L( I3 r% c% d4 N5 }
return m_bAsyncFindRunning;* N2 V: y0 ^+ D" Y6 s
}4 R$ D# {: E9 ?! N: _( x7 J" b k
- C* Q( b0 I- a: g! s' j- Y. [9 F- M/ B5 Q5 j9 o
TRISTATE m_bUPnPDeviceConnected;
' u$ N- j- a; d% R5 M( ?- H& z! x
5 U5 _ \. |$ J: m d1 _% s0 J* I0 k8 W* m6 m4 P: N4 E& z Y
// Implementation
0 M8 g7 d9 W1 \- _ // API functions
! J0 J' }* Z+ H8 @ SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
4 L. R$ u/ Y2 g$ O3 ~+ @* C SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);3 p% U2 u+ s3 e) q8 ]
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
( V" c' t. }0 R% o BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
% F1 `% d6 M6 f9 }8 G BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
7 \9 F/ }. b. p p, e BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
( b9 G6 Q5 F' Q) X
& o& g3 y0 f9 c/ G4 g3 X4 E2 B' S3 w* D% z
TGetBestInterface m_pfGetBestInterface;! a# Y; X7 f/ N0 i+ a
TGetIpAddrTable m_pfGetIpAddrTable;8 ?- n) U6 J, M9 L! ^
TGetIfEntry m_pfGetIfEntry;
1 b. U" R, E* v2 f: v
- m" Y8 j+ h, h9 [9 E$ O/ w# M& ?$ g# h9 J. [# C2 i
static FinderPointer CreateFinderInstance();# F$ B1 q( E. i- H: @
struct FindDevice : std::unary_function< DevicePointer, bool >
5 e' z( `: |& }2 w( B. e {
) Y: }( V+ t/ U+ |: Z+ R6 p @ FindDevice(const CComBSTR& udn) : m_udn( udn ) {}; o/ |7 [: c2 S p! l. w9 ^
result_type operator()(argument_type device) const
& T- |. i$ L/ M8 \+ t' j2 K {
. e- ?+ x1 z! l+ z. r3 g% d8 Q1 { CComBSTR deviceName;1 _; s8 B6 B, K7 a+ P; @8 U3 S8 N
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
! {4 D: a) ?2 H ~7 P; F( T( z: f7 ?
* a0 S3 L$ Q% e0 w6 _/ B" A
if ( FAILED( hr ) )) q( r& G% Q6 Y) w
return UPnPMessage( hr ), false;
2 g. e. |0 o( c$ r2 K' S9 |1 e& h2 `9 L
/ K3 Q3 E# ]( F. e' }: q0 [: L return wcscmp( deviceName.m_str, m_udn ) == 0;7 V) {2 ^' y0 ~1 ?) d X
}
$ Q1 |3 t1 u' d8 w* E7 o( q$ V CComBSTR m_udn;( l @: v* ^" z% A0 s: }4 c
};+ Z% F( ]4 q6 u; j1 X
. ]3 b3 H/ s+ _) `! D void ProcessAsyncFind(CComBSTR bsSearchType);3 Q9 o G$ p0 \$ J; z
HRESULT GetDeviceServices(DevicePointer pDevice);8 h8 y" x6 j5 m) r6 t J n
void StartPortMapping();
6 W; \# G' }* m' G! Z- T HRESULT MapPort(const ServicePointer& service);
- O) Q. r( B4 N$ |4 @+ e void DeleteExistingPortMappings(ServicePointer pService);
4 v9 p% E! Z" i" J& L: C) y6 K void CreatePortMappings(ServicePointer pService);
7 Z% s; @# B: x* f6 ~$ h HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);7 F- k U& w/ n+ ~0 f
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, . _# ^6 R; M N2 `
LPCTSTR pszInArgString, CString& strResult);
. X" w/ s: v+ a void StopUPnPService();$ p1 d2 E1 `, I7 q. `6 ?
9 s, v& B7 T2 {5 [2 V5 J+ F4 R% D4 Z$ I% _& m: a: |' a, s
// Utility functions
* R2 X: H6 }2 I6 C* o HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);3 g' f0 L% o, L. H
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);4 b4 h& C |# }" L
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
" T5 f$ V( A: ]* x2 d+ t void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);4 p' n/ `) x! ?
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);8 q8 ]4 Q5 K8 Y3 r
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);* W C. W' E7 [
CString GetLocalRoutableIP(ServicePointer pService);: D' k9 x4 f" ?: I$ f
( T& X# _9 R' n% { _7 A5 I
+ L6 r/ I& e( L4 R; s, F// Private members# u) @+ R7 l; E' c4 Q+ J& f
private:
- l, q( E7 B0 ~# l) Y/ k; Z DWORD m_tLastEvent; // When the last event was received?* |+ ~1 s" k% j7 j9 ?
std::vector< DevicePointer > m_pDevices;' V- e2 e' }$ G! C; F; q
std::vector< ServicePointer > m_pServices;
2 |! U3 U# r7 u# L! o) ?! ?8 @ FinderPointer m_pDeviceFinder;
; P- w+ R/ \8 G- f$ @+ S DeviceFinderCallback m_pDeviceFinderCallback;
5 K% A' ^0 w; v0 @, c ServiceCallback m_pServiceCallback;
2 U/ p: @- ?* | r0 ~. O; v2 I& s- S w- Y
; ~5 o1 w# ^! o& |* Q* U" Z LONG m_nAsyncFindHandle;+ o' B! O6 `+ f! l0 ~2 O
bool m_bCOM;7 ]: M; H* Q% j+ k; j2 t
bool m_bPortIsFree;. Z4 _0 k7 n0 {6 B
CString m_sLocalIP;
' ~6 q2 j/ m4 [9 T4 I1 x CString m_sExternalIP;% Y1 _& W9 Y- I, ]+ k) Q
bool m_bADSL; // Is the device ADSL?
# T4 z( W4 E; _! M) o5 ~ bool m_ADSLFailed; // Did port mapping failed for the ADSL device?' B7 F( p8 v7 x( c" o, Z( V
bool m_bInited;/ h0 R) b5 [1 @3 c1 k$ I# h
bool m_bAsyncFindRunning;/ Z' a- g+ ~. S x6 Z
HMODULE m_hADVAPI32_DLL;
0 b5 E! g+ t6 l, u HMODULE m_hIPHLPAPI_DLL;
5 O9 C/ I. Z; }" a bool m_bSecondTry;4 |2 C7 \3 ]$ W4 A, R) t" _
bool m_bServiceStartedByEmule;- T3 l" r1 C7 ?% j0 f7 W
bool m_bDisableWANIPSetup;" t1 y6 e' o' a: b! e
bool m_bDisableWANPPPSetup;
! N2 j2 s- J+ J, O& a& A" y' e, K
' w) U. y5 P7 g; Q. V+ k
8 `& u& {. V; v, r" n0 [$ Z" W};
+ R5 s1 ^: O, ~* c3 Z8 R3 q9 R, s1 d0 K! J4 A1 I* c* Y
, C M8 a$ b: a& Z9 t& E// DeviceFinder Callback
& d, p4 e _* Q% y1 Kclass CDeviceFinderCallback# y ]4 _( I, d( O1 ?
: public IUPnPDeviceFinderCallback7 M6 ?: ?- H- B" b: I
{
b4 u; F; R1 ?- A" u3 Lpublic:, D& s! } {/ p* r4 C
CDeviceFinderCallback(CUPnPImplWinServ& instance)
' |7 k& @$ r5 ^ : m_instance( instance )
- }# R- E! c/ f, U { m_lRefCount = 0; }
0 ?0 B- k a4 h6 }- \% R
: p8 J) g6 ]0 g# M$ p, X: s2 i" w j8 p
& c0 T/ b- U' h- b- M# h, H STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);2 z4 K4 B7 j8 N1 d0 ^* V- f: p
STDMETHODIMP_(ULONG) AddRef();
+ N$ Q2 {$ M! Z7 a. D' g STDMETHODIMP_(ULONG) Release();
& S! u* Q. f6 U1 h- [- c) H- R1 T: \8 X3 p3 u
; S3 S) S/ `5 e: Q8 {) n* K3 @
// implementation
* v5 h5 E" P! f5 ?8 i0 [private:
, b' a. p; Y6 e' E+ d% [0 L HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
8 F, i7 s7 _* b- H1 L HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
* K/ r6 \2 V- Y; P }" G' _" l# j HRESULT __stdcall SearchComplete(LONG nFindData);4 \8 B6 l3 M1 B+ L! c
# n9 p% N% Q0 i, O; e
' F/ r) {8 e6 b: V4 T# m5 @
private:. f2 Q2 ?6 T, _% M* D! Z# d
CUPnPImplWinServ& m_instance;5 }* y1 p4 d' I0 ~$ |& x. v
LONG m_lRefCount;
+ G/ P2 m, _4 C- }6 U; S};
. D4 |# |0 ]4 w1 _
' r# r2 ~& m0 y! I/ C- @ a* n7 x" r* s: T! z+ S Y# T
// Service Callback
! u v) l t! Wclass CServiceCallback8 Z! y+ X$ f9 N( r P( f9 u/ p1 W
: public IUPnPServiceCallback+ W% e9 E8 a% q9 K# ~# s4 n
{
; ]* L4 @6 O4 M8 _, O5 Rpublic:
- H+ ]6 [$ a' ^4 _% ? CServiceCallback(CUPnPImplWinServ& instance)
% G8 X* a2 Z, S: A8 F : m_instance( instance )8 N* h7 ^% `$ |7 V \) b) Y
{ m_lRefCount = 0; }5 \/ s- k& g# q" L) p+ W
+ j5 ^5 B" f: U6 X' F! ~! t2 w
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
. w% ]: q6 f* a# @ STDMETHODIMP_(ULONG) AddRef();* o3 H' z' v7 n4 h
STDMETHODIMP_(ULONG) Release();2 D1 @6 n- I/ y) V# E/ T) a
' b2 Z1 Q- p3 K- n8 X6 E, V# x! I: G/ J; u# G
// implementation
# l; c$ n+ n9 |. e/ w" s, lprivate:
6 ^( e+ E; @! Y# g$ }3 E$ |0 r HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
7 c' f: w$ W: M! f HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
3 Z8 E6 `% X0 M+ ?& M+ w3 d5 U" S: c& J- y% ~
6 h: `* `4 H8 \private:
) e0 v4 ^% E. B5 ~! s CUPnPImplWinServ& m_instance;
! L& e% q" U+ b3 z7 ` LONG m_lRefCount;: U) K6 q; ~2 L L6 k- l/ g
};
$ ]8 ?! H( S& l' I& u/ e6 R; [, H6 M, ^, K
# G1 E0 v; I/ i/ M- }/ ?
5 c6 t% {. E" f! r4 n5 @- _/////////////////////////////////////////////////5 Y l5 f* l8 r+ F
4 ^) _! _' ~- v B3 a p3 P$ w6 w @
使用时只需要使用抽象类的接口。' Z9 o x* H3 h! B Y' @
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
9 }# X1 h- M5 @" X6 F# kCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.0 S6 H; ?0 C/ Q( @* h6 Q5 q
CUPnPImpl::StopAsyncFind停止设备查找.
( T7 |9 C# G; l; {# p+ KCUPnPImpl::DeletePorts删除端口映射. |
|