|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,/ Z2 Q9 y5 S4 b' f! D
# n2 G& g! A- t' F' d, N: P+ `1 G, z/ R0 M* r. ]1 q
///////////////////////////////////////////
3 U$ D: Y3 n. q$ c- Q5 `7 W' O//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
6 _* y+ W/ R3 U
% }; A% V8 J+ ~- \/ ~. a+ w$ `
% G5 L- i0 u' k2 @# v4 A+ N4 X* O7 c#pragma once' ?2 L6 z* r" r K
#include <exception>
- ~" [# W. I$ A4 j
- p$ b0 A: S0 n6 w5 x
7 p8 v6 L0 F) Y$ A I( O4 b+ x* ~0 B enum TRISTATE{
/ q* i% T6 q+ |& `5 T5 i8 z TRIS_FALSE,- Y: s7 c' |2 r Y8 [5 X8 \
TRIS_UNKNOWN,
( {& Q' `( \5 F- V TRIS_TRUE I5 p" ^/ v D+ P/ j
};3 G, p/ x* ]9 F: c: K1 e
1 e* ]" b) z4 i' Q% ]+ `- i6 Q0 Q9 O
enum UPNP_IMPLEMENTATION{2 n& {- I( A/ v9 Y8 r! K
UPNP_IMPL_WINDOWSERVICE = 0,
! W0 h! v5 ]) m( `1 `: c4 M/ W; M M) I# X UPNP_IMPL_MINIUPNPLIB,
y* P3 l& r% v3 M( L UPNP_IMPL_NONE /*last*/
6 n( D. [ e3 T};0 e! X1 d* k" [/ ^
* z6 h" q9 d8 M, j7 R3 A
. f$ @ k5 |1 V% e( w
& A) s B$ n! D3 x" q4 v% x
7 s9 w f4 z; D$ H+ uclass CUPnPImpl$ S: h5 j0 F' I% S4 V
{9 c" ?# B/ |4 s1 z" @0 e
public:3 Q4 t0 I! _3 o& G
CUPnPImpl();
/ f$ G1 ~! j# M) t6 M virtual ~CUPnPImpl();
5 L/ q# O: u: @& R+ H U, X struct UPnPError : std::exception {};( T& @% y) g+ U' Y
enum {# j: k7 w, {( e) E; }# f
UPNP_OK,5 q7 L* n0 F$ p. l1 I
UPNP_FAILED,
, `$ m" q2 l" e: v0 X# e/ v, f UPNP_TIMEOUT( w2 c- h. ^9 e' s, m" b
};9 j; ]3 C# }; R4 s6 A4 A
8 ?/ e" Z; o# K( x
3 [' ?4 z) U+ U' u! {1 ? virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
% Y1 Y2 y4 d* y9 c: | virtual bool CheckAndRefresh() = 0;
; l4 ^0 n) Y; }1 V7 h5 S, W virtual void StopAsyncFind() = 0;; I3 f' D" O/ {) p
virtual void DeletePorts() = 0;
. |; f) @; O. n virtual bool IsReady() = 0;7 R2 l; D- C8 ^& G% f5 J
virtual int GetImplementationID() = 0;
: K7 a8 @6 G& ?+ s% z
/ _7 V% }0 e" _- I8 B! n b4 L void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
/ j$ N. }' M& X* I" [3 z9 J1 {; _: d7 L( z
T& D, ~* i/ u" g2 E
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
& c/ R C9 j/ c' n" B3 s( K2 h TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }2 H4 I( q; v8 A& @7 U9 d+ B
uint16 GetUsedTCPPort() { return m_nTCPPort; }
$ D1 f! i" j" v" [ uint16 GetUsedUDPPort() { return m_nUDPPort; }
) @" M/ n3 F1 M( ? l, u' f. K# A% q6 x4 f/ c
V& Y; e8 [+ B! ?* p% Q' S) {
// Implementation
6 _2 E$ ?) I! Yprotected:5 C) s. o4 m; e, a z
volatile TRISTATE m_bUPnPPortsForwarded;
, U8 P+ P2 D2 g0 n$ o1 H4 F3 `) k$ ] void SendResultMessage();
1 h+ I: X: _; ` uint16 m_nUDPPort;
, }- Z7 I8 S1 T i uint16 m_nTCPPort;
2 V* R9 W1 z+ B) r) w, Z4 h" t uint16 m_nTCPWebPort;
3 f" V# R ~" G bool m_bCheckAndRefresh;
" h: _' c) q8 ]8 I' j* m( w/ D& t4 v; ^& r
) I2 W7 ]4 n9 q, p9 Oprivate:3 v% A# Y; [+ i! v6 r
HWND m_hResultMessageWindow;
! y0 D$ {7 i0 B8 t+ I% z) t( X UINT m_nResultMessageID;$ @$ s: W C. w, G4 ?& |% }
9 J/ _& C9 F- C* B% I7 g
4 s8 ^* k* H! O$ b; E};* A8 {5 D9 v" L: {3 v2 _8 I9 J
1 U3 R3 c u% g) x7 c/ u% C% G
5 R2 ]8 G% ~0 `; \4 A5 N3 Q
// Dummy Implementation to be used when no other implementation is available
# R, s% x# r3 H0 ~, d: lclass CUPnPImplNone: public CUPnPImpl5 D2 _3 C6 B& X3 F( _8 o' F
{( `; J0 o9 _& m$ G/ E) l
public:
5 {/ P; T9 o+ Z: K virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }$ ]( k- B4 Y7 ]) q% G) n
virtual bool CheckAndRefresh() { return false; }
6 v/ d, t. R4 h" J t( S virtual void StopAsyncFind() { }" W, d' n/ L5 X
virtual void DeletePorts() { }% G9 S" o( B& h, b/ n1 U
virtual bool IsReady() { return false; }
3 @% c6 C+ }" W# W virtual int GetImplementationID() { return UPNP_IMPL_NONE; }4 k" I, B5 h" q& N3 n& I: H8 E) L% K' m
};
7 T5 r& H/ ?* T) q' z/ E1 N4 h
9 o' O$ Y6 D' Y
+ {) }/ E \9 T$ I! z6 v/////////////////////////////////////5 W8 t5 g& V8 w9 o
//下面是使用windows操作系统自带的UPNP功能的子类; A& | y% V5 W; A( E
7 v$ `/ M7 y/ d6 y0 S
) v- g7 n/ }/ b/ K% i: b/ q#pragma once
7 [7 j7 w4 |# Y+ s8 Y/ f( S: D+ a+ Z#pragma warning( disable: 4355 )
* ?' v0 P2 F# }* a' L7 }5 h+ `* D. j! L g: Z f
* e6 t2 A) [6 B* l! W#include "UPnPImpl.h"2 F$ i% m1 O- E) O+ p
#include <upnp.h>' N( w% G& Z3 t( ?
#include <iphlpapi.h># W' e' T. B6 K5 K7 s
#include <comdef.h>
6 r( T/ E) U5 {) R: b8 j#include <winsvc.h>
' H4 G' g& f# ^1 u1 o& a
* g8 j* z( B8 \% K6 i' n. o/ N
* A9 E0 h9 l" B' d& o$ A s7 R#include <vector>
( T$ J$ E8 ~% J#include <exception># C0 j$ {" Y* z3 m& K, q6 x
#include <functional>
" @& E3 l W8 {0 N! U* A# f: h( }8 [+ N4 h5 T4 g. J7 n
M( T/ U; j$ w ^9 W" k
) x/ O) l4 x) G2 i
- V+ P; U4 g3 Y" g$ p% }3 ptypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;# H$ e6 q4 V4 { }
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;. t- F, B' R0 U6 Y% d2 E
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;& H4 j8 C$ \: i0 i+ k o( J' k
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;* G5 r# q; F3 y& }; d# Q
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
2 z* S% H8 Y6 M: [typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;7 n4 Q! _, \& a7 e
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;7 W- x1 ?1 \+ l. }* p1 u/ h% l
; i/ {! L L* U
. r& w" l2 ^- }2 z& R4 b1 Otypedef DWORD (WINAPI* TGetBestInterface) (* e9 v$ u; Q: G! C$ i1 Q5 z3 r6 d
IPAddr dwDestAddr,
$ F/ R" k1 i' r+ x! X% T PDWORD pdwBestIfIndex1 a' {; ]/ f) q/ l& t
);6 {( z+ c5 k( Y
% [* d6 }+ B b, I! a! n- }7 U0 d* O: U$ |2 }7 w) I
typedef DWORD (WINAPI* TGetIpAddrTable) (
# z3 x: I7 ~. | PMIB_IPADDRTABLE pIpAddrTable,' m8 B: \1 D) b# j9 X
PULONG pdwSize, @" w' a4 I. r Z+ q! O7 a* F, U
BOOL bOrder
6 }7 p2 o4 K6 W" y);
! I; W' ]- V% N! P+ S- p9 I0 n7 w5 U, _' h3 F4 U1 J
/ {1 M; g* M& y4 e& }( ttypedef DWORD (WINAPI* TGetIfEntry) (5 P8 a3 ]$ [4 p& Z
PMIB_IFROW pIfRow
0 P$ N4 a: f9 F5 b- e);
# S* Z9 S' i# F; {( W
3 U4 x/ M+ o0 k! h8 s6 F0 s& J3 e5 ^+ v1 b1 R. H$ _
CString translateUPnPResult(HRESULT hr);
# w% p- p* o# w/ c& }HRESULT UPnPMessage(HRESULT hr);5 s9 [+ F7 t: y9 x
0 k3 a* m0 H; Q0 W% R. N# @7 s. [6 g: A7 ^7 t; B# F
class CUPnPImplWinServ: public CUPnPImpl
9 I/ O" ?6 c7 d8 \# B( |: E/ \{
. R" @& E x" I1 C+ ^) N friend class CDeviceFinderCallback;. y% V4 W* m2 }8 d6 o( e
friend class CServiceCallback; ]) q$ }# M9 S0 o2 b4 F& L
// Construction' t, r4 Y( }+ D
public:
- z& l& E, N6 z. J virtual ~CUPnPImplWinServ();7 F: z9 u& a4 V4 \1 X, G" S: p
CUPnPImplWinServ();
( W, A/ a, | V1 p7 X' F; c/ w- P: W! N, h9 e5 a# G7 j- B
G8 S! T& m1 E% d4 a
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
" s6 b0 h3 P6 c% V7 D7 w virtual void StopAsyncFind();6 T) C& Y/ N& x' [7 K1 Q
virtual void DeletePorts();
: m, B2 l# G* [" H* A4 P5 I virtual bool IsReady();
5 D+ S% A i) R6 l7 S# r0 z$ p virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; } C' ~: r* t. s- E3 [3 U7 Q# h
3 p) `2 F f% I
, B8 e# O- d: A2 X$ J* `* T$ h& a) n // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
; Y) W, R4 s& n9 q2 T // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
9 A- `9 A) Q6 f5 i- N1 O virtual bool CheckAndRefresh() { return false; };) n: Y& J' s. s7 c7 x
1 q- b4 G+ Z0 {4 y; x: z( D) f7 V
, N8 d' a+ B* k2 c6 k/ Z1 Q
protected:
/ N6 r* w, v0 m: r void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);- r1 q- ? q U# D* W. T
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);' Z( m- I, h+ H( f- d( C1 }
void RemoveDevice(CComBSTR bsUDN);
7 X* K# W- p( h! Q" I bool OnSearchComplete(); c9 G% M6 \/ N, Z
void Init();! V: U/ I! y1 k7 v
3 E; H; m/ ^, U2 d- S
: `! w( m( W3 q Y+ x# ~( c inline bool IsAsyncFindRunning()
: W) |4 g `/ ?/ c# A. d {
5 u1 O7 _( F: ]6 Q) Q8 @/ K7 \ if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )$ |' w9 x2 h! }- z7 K' {( a9 r
{
$ g2 l- s. D `, f+ q: x% u" f& j m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
0 O, M1 M: i) b1 D e" R+ J$ O m_bAsyncFindRunning = false;
# g/ R) M9 l* ^+ Z# S7 t2 t }
; w4 p: l* u) J' G" Q: Z MSG msg;# M, |- C* [* [' x
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
/ ~" y N4 B6 \* I# K {
, X; n' Q7 w& I! P; d TranslateMessage( &msg );, c4 o6 W( g$ e7 Q) U/ t4 t( e& S
DispatchMessage( &msg );! i# @. x, a" S: z$ k4 B3 I3 h
}
, x! u9 I( i, E: {# n& ~, E+ T return m_bAsyncFindRunning;
& r& W+ T' {2 ?: j) ~ } e- Y" n* Q+ b# B
- m# |; e' a; V! @% {
# B+ u# H) o6 {7 S7 A: Y7 A
TRISTATE m_bUPnPDeviceConnected;' L$ ~" U7 R! I+ C7 b7 `
$ D& }# _: K& t' M
3 \# T9 C" d% b$ }// Implementation
: n$ i8 d6 c% v5 l! N // API functions
; ~) F2 R- {7 X$ d$ I SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
2 Q( L- H" k- y SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
! F$ M$ r+ u* ]. Y6 n- x6 q BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
2 b4 M, z t' z3 ^7 R/ z% s BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
% }9 g. W$ b& v3 Z BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);9 h' V6 K4 t) l
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
8 Q- } R9 g+ e& C6 b( _2 I; M) w% V5 s: Y$ a! R- r6 j% I, @3 X
& Z r. `; s7 D+ P
TGetBestInterface m_pfGetBestInterface;- f+ ?! R) C% F, r
TGetIpAddrTable m_pfGetIpAddrTable;7 n) }- A1 S+ }; |
TGetIfEntry m_pfGetIfEntry;
) {% @ k5 B. s" V
, O, `# F1 P& b; E6 H6 t
2 f( x' O+ E+ R static FinderPointer CreateFinderInstance();" q) F. i3 }& g" g7 f* Z' u
struct FindDevice : std::unary_function< DevicePointer, bool >8 D3 Z, |2 t) W
{ O( w! t* D2 c! \3 p t; o
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}2 y; `, }- x6 p- `. q2 ^
result_type operator()(argument_type device) const
1 V5 i" B L4 p, e/ F. g# B9 _, |! ? {; q% S, _. N+ ]7 u
CComBSTR deviceName; @: \+ G8 q8 Q8 J. C7 z
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
- P3 K6 z0 g* `8 ^6 j- _; o4 Z
" t0 P, K* N8 @0 t1 W. e% p
3 C7 W5 @2 {, i/ w$ q if ( FAILED( hr ) )& z; L& A6 S ~+ s
return UPnPMessage( hr ), false;. @/ ?. {, i) o- F9 F6 j
# Y* ^" t& X2 D2 c9 g0 W
' V. y9 L! J8 t! N% g% M return wcscmp( deviceName.m_str, m_udn ) == 0;
7 x* b: c# V' U* t1 D5 [3 ]/ ~& W }9 v( m! |" `9 x6 @8 Y
CComBSTR m_udn;
& Q6 Y5 ~) R7 ]! U! W: [4 a };
9 g' I8 L5 b8 A N* ] ' ^4 z2 q1 m6 I2 m2 [; b, W% G
void ProcessAsyncFind(CComBSTR bsSearchType);
: i U1 E4 k$ g/ U2 a! z HRESULT GetDeviceServices(DevicePointer pDevice);# `9 Q. J) T$ W2 d3 B; X
void StartPortMapping();
: ~" \4 A _$ t; {, J0 `& m HRESULT MapPort(const ServicePointer& service);% E: g# D+ r- O
void DeleteExistingPortMappings(ServicePointer pService);" ~; C0 g! Z: r0 l! L- E- q* f) P
void CreatePortMappings(ServicePointer pService);
: I4 F0 b8 w: t' t9 a7 v HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);+ y& f! V8 J3 c0 W2 \+ i- M" q
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
* f3 b% p- W3 N/ c( m LPCTSTR pszInArgString, CString& strResult);
4 a8 B- K9 w* {7 o% ^. \- b void StopUPnPService();8 o" O, V* z, v4 E6 p) }
& i2 r; Y1 h6 g' `9 Z8 @
/ _1 ?3 z1 q4 r( R" T1 e7 L
// Utility functions$ G, _% ^; K" A
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);5 J# y4 R" ]' m$ a# ?1 W' _! ^
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);" U& @8 K# S! B
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);5 o4 m8 C1 W0 T- a) G2 [" d* O4 k" ?, f
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
8 ?, d; r# s- }/ ^5 b HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);- |3 ~' j2 X, U5 C5 Z3 M( S
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);. C; k3 u8 L- a% `6 D5 n# {- E
CString GetLocalRoutableIP(ServicePointer pService);1 |4 N; D4 F/ a4 o* w
, j. r$ B3 K+ {" ^" k8 y Y
9 Q3 @# I M7 t$ |6 H6 F
// Private members0 l5 I7 K# u |, c% [! `
private:/ {, ]( H: `7 e% _ M% [* H: i
DWORD m_tLastEvent; // When the last event was received?
) e% H( [2 h6 S+ b/ m std::vector< DevicePointer > m_pDevices;4 g4 R! w1 ^6 n6 V# G( S) s: Z
std::vector< ServicePointer > m_pServices;* E$ v# \ c6 g7 t q
FinderPointer m_pDeviceFinder;
' |' w( E+ L2 q7 y DeviceFinderCallback m_pDeviceFinderCallback;
& l, O7 W3 k6 O% d) N" V. | ServiceCallback m_pServiceCallback;
' b) _; S) Q$ y' x
1 G, e4 x5 F9 A8 Q2 }$ \
* T+ q3 F5 J6 x2 [# p) S LONG m_nAsyncFindHandle;+ R: r9 x- ]$ P0 X) n$ ~5 I
bool m_bCOM;
6 ^( d5 W2 _. ^4 c N1 j, ` bool m_bPortIsFree;; |% w- F1 H0 [' e- `1 x
CString m_sLocalIP;, y: A: ~8 @9 w+ d! D; F2 Y% Y
CString m_sExternalIP;
# f, O( F/ P6 l* e8 i" W5 w0 b bool m_bADSL; // Is the device ADSL?
% r5 d8 d, f. N l6 O bool m_ADSLFailed; // Did port mapping failed for the ADSL device?) S: X% b+ z- {
bool m_bInited;
2 }8 c1 ?( k$ z% Q% M: C9 M bool m_bAsyncFindRunning;
7 [7 W$ r! S+ U7 T3 W HMODULE m_hADVAPI32_DLL;" }4 F! l( r- h9 D" Z I; L* H
HMODULE m_hIPHLPAPI_DLL;+ Y& \0 \: G3 I& n4 g$ w
bool m_bSecondTry;% ~% _ O- S5 n
bool m_bServiceStartedByEmule;
5 l* w) c! U8 Y; S4 o% O bool m_bDisableWANIPSetup;
* b% Q6 G; d2 A3 G0 k% f bool m_bDisableWANPPPSetup;
5 j( r& f; G" G, H$ p; _% A
7 Q/ m( {# K3 `7 E" ?9 I0 l ] l4 n- A, r/ ?( {( x
};" v- n* O' A" g9 F0 `+ f) Z$ U
( M- o3 A/ w8 I4 k8 {4 r
) z3 |* W' ~7 r" {. F0 f// DeviceFinder Callback) z" O* x4 u. I
class CDeviceFinderCallback: m. ]+ m) l4 A' b) s
: public IUPnPDeviceFinderCallback9 |. A* v8 P5 K; l4 U
{
% K/ W" V, d0 w ]/ `public:, Q; u- }+ H5 `7 x, M4 D$ d
CDeviceFinderCallback(CUPnPImplWinServ& instance)( J c' I) H1 O. {
: m_instance( instance )
3 m3 S3 j/ l9 u5 ? { m_lRefCount = 0; }5 q2 N2 [( O5 _/ g) N
( S& i6 x. S' q) @
) T7 `6 ~$ r8 K. a J
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);2 [2 V4 x$ ?7 T: ], f# ?& j; u
STDMETHODIMP_(ULONG) AddRef();
6 `' w; O# V F/ P STDMETHODIMP_(ULONG) Release();
' L! m- G$ ]" d, b4 Y( S0 S1 J2 R, w' u! d/ ~+ E6 M3 }$ I1 C
5 T" m8 x8 b! \: E a4 O, m9 G// implementation
: L. G# l, g; W' y3 P$ w# w1 }private:
: U% E/ o# m/ R0 p7 S& J6 q& Q3 S6 k HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);' L8 c7 I4 |/ x3 P
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);8 a$ t3 j) @+ a+ X4 d
HRESULT __stdcall SearchComplete(LONG nFindData);( z5 h! U7 h* f' o
2 u. i; L1 H9 t& y4 y/ ~
$ |3 Z! {0 g6 ]8 [! L' b6 h* Fprivate:
! q) K1 h$ a: O CUPnPImplWinServ& m_instance;/ y, A& m0 P. G
LONG m_lRefCount;
U; b6 \' B: z; Z/ j' m x, y9 H};/ z' E" J5 o: I6 p
; U$ @5 ~; R& m& `
) M, h' T3 J" _ i0 D// Service Callback , t5 i3 u/ z" X
class CServiceCallback4 e2 d# E& O" O
: public IUPnPServiceCallback' h1 ~, |& T1 U! F3 r5 L
{1 Z2 e* |( w% l* ?8 ^1 p, t
public:
* m0 ?# @) Z7 B9 r' q CServiceCallback(CUPnPImplWinServ& instance)
6 z+ P. S( w8 h' u3 n! N5 x; R : m_instance( instance )
1 {* e0 G, Z( r6 A+ a% g { m_lRefCount = 0; }
) l2 \5 ]$ o; R7 m" c 7 R2 H! h( K; [
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
: z' P: v6 Z2 V4 D0 G STDMETHODIMP_(ULONG) AddRef();; b8 H5 Y/ W! Y& g% n
STDMETHODIMP_(ULONG) Release();
) {8 D$ a' w* `% W. ~( W$ I5 @9 R+ h G0 B0 e% c
+ P( x: f E* K j// implementation# Q( ?" q: o8 r3 m, i0 i4 J9 L7 \* u
private:
, A9 ~8 S" }9 w' ^( ?% L+ a HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);4 P2 u( b/ o5 j. ]. H
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
0 @0 c1 V% F8 Q& |% J
0 F( x2 i4 S. i# @) g5 }
9 {4 t/ H; c" Y* G. X$ Eprivate:
/ d) j) y- m5 y CUPnPImplWinServ& m_instance;# g* ^8 ^6 h" N1 N
LONG m_lRefCount;1 Z; _, e" x2 |* G4 I
};6 W6 J C* a5 C# V
: T/ y+ w9 } V; i$ j; G2 K
3 p- a" {4 `. P" t/////////////////////////////////////////////////
* |3 ~& L- |- i( @$ p3 m" B! m4 y# h1 {+ M% r7 v$ j; w# k8 A
+ h0 y1 b) x7 f" l" t; l
使用时只需要使用抽象类的接口。
, I3 }# U, g& G1 I3 UCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.; K% i; M% e7 T0 L, c- `
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.! n/ y4 k5 F8 g
CUPnPImpl::StopAsyncFind停止设备查找.% E1 L% X" p6 t8 k6 P# |
CUPnPImpl::DeletePorts删除端口映射. |
|