|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
7 R( }: [" h8 O
1 x+ S* F% W$ }$ x: x9 e6 [/ ^- m2 c9 p0 s( {2 d/ A8 T9 L% `
///////////////////////////////////////////
' ?& ]5 W7 \4 i8 Y//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.) z/ O" `7 ~" I+ B
I3 M* r2 i r3 V' R
X2 x6 s/ }. ^# \+ Y#pragma once
) \; [; m. Y0 o, ?#include <exception>
7 b. \* s6 l9 O( F* [* Q1 i3 G; H }% [3 G1 Q
/ K: P9 V8 U8 t" ~ enum TRISTATE{/ \. x% v; A6 z7 r5 k
TRIS_FALSE,$ ^- }! \9 I0 s) o
TRIS_UNKNOWN,2 K4 S; Z6 x# |
TRIS_TRUE
5 \& R9 ?; X* a* H5 V5 ^: S};
' I5 v9 e" c- P% P% _& ` U- o2 l/ N( R6 f! [: i7 t! B6 ^
* M; {: ^; k" L& r( _! Genum UPNP_IMPLEMENTATION{
+ C- I1 v8 K4 Z2 i- a UPNP_IMPL_WINDOWSERVICE = 0,6 j/ q4 z* P- O% [$ D# h
UPNP_IMPL_MINIUPNPLIB,+ m% V4 ?( \9 O: G% Q) h
UPNP_IMPL_NONE /*last*/6 z9 v& _4 m$ E2 A2 Z- C
};
! r, \6 V7 C+ Y I9 p7 X3 K+ e( m6 Z' F. e: T4 j% e8 w
2 ]2 Z7 I% a$ p) e& A% d
5 ^5 e# }, p' i7 B G
, N! O `( n$ [2 q; }; d/ S1 ~8 ]' Eclass CUPnPImpl# Q; |0 g! D+ o
{0 h) M. g( k: U7 _; a
public:; N: u* G. v' b t# b7 I" |
CUPnPImpl();
( C# y+ z; n+ c5 B7 N virtual ~CUPnPImpl();
& H% ~ @8 v* A+ }! ] struct UPnPError : std::exception {};
! l6 ?9 @( C8 N0 @( w enum {
+ |+ ?5 `7 l6 H! a% _; ^ UPNP_OK,
* g& W, _2 `6 n% h UPNP_FAILED,# L4 f9 {0 C/ w# p ^) s; q& `( Q
UPNP_TIMEOUT* |; A ]0 x9 d1 r
};% X0 C i' u: f+ t
9 g2 ^3 b5 L0 S9 ^
7 `. W' K, ]- n virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
/ _7 u' G, G" I/ K0 z# r% U virtual bool CheckAndRefresh() = 0;4 G+ ^* B) p. X* g% H' t
virtual void StopAsyncFind() = 0;! q8 p# c+ s6 l! c) o
virtual void DeletePorts() = 0;+ C) j0 j. A- ?$ h. k9 ]. u7 V7 q. C
virtual bool IsReady() = 0;
! {$ |; X. b4 B5 ?5 q' d: x virtual int GetImplementationID() = 0;& {4 V7 Z0 x0 J1 v& x* b* T
$ Y5 q/ h, a& G' V: @! O void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
; e3 P# K3 s# }3 ]0 _; {3 a
+ a; w( R: J. d5 [% a* t* T0 v. M) O# y9 ~4 V) w8 v' ?
void SetMessageOnResult(HWND hWindow, UINT nMessageID);& V- i# K8 F, E( C
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }! @$ N! ?7 Z- r/ u$ [. b
uint16 GetUsedTCPPort() { return m_nTCPPort; }
- H0 r) \5 U8 \0 n! f uint16 GetUsedUDPPort() { return m_nUDPPort; }
8 q4 A, T h t& k% m8 w7 T9 e9 W# l" r$ B# n! Y
6 A# d2 r2 e1 K; f- T
// Implementation7 K/ T6 n1 c( E, F/ Q
protected:
9 `; W w! J) N; X6 y volatile TRISTATE m_bUPnPPortsForwarded;
4 z, L- B8 F! T+ D0 s4 D void SendResultMessage();; D( @- \+ G# F7 u% Q: I
uint16 m_nUDPPort;
# @- J3 I7 a1 D% W: W8 j w0 `3 V uint16 m_nTCPPort;$ j3 [$ L: N0 m9 D& e# G" o
uint16 m_nTCPWebPort;$ Y* j* z! _6 k2 R' U
bool m_bCheckAndRefresh;
$ G5 m7 }0 I, }0 i: P6 c# y# L. \1 }5 t8 T1 X4 F
; W, H: W; S c5 ?' K7 v2 G2 e
private:$ i$ _8 X9 h. P2 F$ a
HWND m_hResultMessageWindow;
$ P" }6 E. N+ d5 g6 Z. f9 G UINT m_nResultMessageID;
4 i$ [1 ^, \: ^1 }$ a% h$ N" g% ?1 z- d) r8 p, n! _& H
( Z5 C7 R2 S. l9 p' @4 m};
% D: A7 C% |% I3 M- B
5 ~9 o* K% E' E+ U6 G$ c7 ]8 R& j, n8 b3 G, @
// Dummy Implementation to be used when no other implementation is available
7 M% ~/ I- J! V2 f& [ yclass CUPnPImplNone: public CUPnPImpl
& I. q4 {) M$ B{
4 i) N# o1 {9 N/ o% m }1 A! ~public:0 M1 o* F% D! W7 I! @
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
) p1 a7 ^& s( _ L; G virtual bool CheckAndRefresh() { return false; }
1 P6 P$ h" S2 A" R% F+ G virtual void StopAsyncFind() { }
. W2 B7 Z! q3 @0 { virtual void DeletePorts() { }
- M/ ]9 ~3 ?: ^+ Y8 A, J6 J t virtual bool IsReady() { return false; }6 O; v1 n2 t' Y5 k9 ^
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
5 L1 A( E7 [( [1 t7 q' i};3 f& G# i' C; r5 ^" Z& k
L$ m) P3 z' w" Q% H
; U0 Y' R# F+ v; l; w8 i1 |3 H/////////////////////////////////////
$ r( V9 Z8 o* {$ l: w" U# T( B//下面是使用windows操作系统自带的UPNP功能的子类
& y4 }6 p) I k( P" q) S; y0 a5 z7 Y; |) q! f+ K! D1 s
d9 t( r2 v, }2 \, g/ Z* V- l. i
#pragma once
! B" n0 v+ u6 X: |$ S e#pragma warning( disable: 4355 ) b* `/ q( M |) a$ L; a# Q* R
5 X' q, Q9 \% a& |% A
* ^; J; x. Y/ R+ r9 O, K#include "UPnPImpl.h"; T" H( K m j/ q! C3 {* _
#include <upnp.h>" i7 E+ Y7 I) C6 }( \. U1 G
#include <iphlpapi.h>
3 ~; I% e& q6 V; q0 \4 J- F#include <comdef.h>: H) R5 L; |, R* E3 m- d. B' m
#include <winsvc.h>, b- Q/ v$ L& \6 \/ m( E
+ D$ _3 ~2 r: M& |
% s" Q- y/ m8 {/ {: C; ?#include <vector>
4 V6 x' o) [3 I0 w; K1 q$ q5 J#include <exception>1 n2 z `3 h7 k( f
#include <functional>
" `& _; R; x+ H* c h; f2 ~4 r- h! Y8 g' I7 p$ D5 R& Z% O
! X( K( {! j& x8 w+ F
5 ?0 S1 h& K2 A$ W& l8 Y4 L: Q" i: A k6 v+ X, y8 H' V
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
; Y3 m7 P" q9 ltypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
( W; Y; b" X8 A! q6 t6 Etypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer; M1 `8 z' L3 k# X
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;) }" Q& f) P' s% H U
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
, N% j/ g. H/ t8 { k1 X5 \typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;& p* @3 l& \) ]5 B) z
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
0 c C& A7 q3 o& E" o# u) D! u3 \$ b) q% z' l% i
* j& U: L* i% p- _9 J2 ?9 Y/ ctypedef DWORD (WINAPI* TGetBestInterface) (" Y' c; O+ F2 j' O
IPAddr dwDestAddr,
9 D3 C% y" z* m" I2 a7 z: C PDWORD pdwBestIfIndex
( s, J! [3 k5 s& z. o);6 v7 |- |: w2 l1 C* ^
3 q9 y1 V/ n# d& n7 b* M
) s9 R$ D9 O8 Y! p A" N' ptypedef DWORD (WINAPI* TGetIpAddrTable) (
+ D6 V ~* o; ?9 H5 m: @1 t+ Y PMIB_IPADDRTABLE pIpAddrTable,8 h# f8 y, @' m6 D4 b2 ]
PULONG pdwSize,
( T% l! }8 |; w0 c BOOL bOrder+ h, Z. @7 l0 B! S0 a
);0 l) w: u+ L6 f+ `3 t' R- J
+ G* B3 @/ g3 v6 k u5 j
- M: R. V4 p3 M8 Btypedef DWORD (WINAPI* TGetIfEntry) (1 n: z: R6 s+ X5 }
PMIB_IFROW pIfRow
: m/ O! Y6 N* M);9 Z+ U" \0 j' u3 i& w. E X0 Y
! a; t! |/ h! k: c4 ^
) G% p4 { O/ B1 I; `
CString translateUPnPResult(HRESULT hr);1 M5 [! Z$ w& X1 j/ Z0 U% G! N
HRESULT UPnPMessage(HRESULT hr);
) k2 O4 W6 }# Z3 y8 @( `5 M" ?
5 D- v4 Y& L8 h2 E
# j# C. f m. a# R2 eclass CUPnPImplWinServ: public CUPnPImpl2 o3 j% g; J8 C
{
) w9 Z8 D& }; q1 }% K friend class CDeviceFinderCallback;' P7 G% x% V! E! b
friend class CServiceCallback;) }2 b& ^$ q$ l3 a6 V
// Construction" `# M* h% |& ^) y; d' C
public:0 A( A% M1 K8 ^
virtual ~CUPnPImplWinServ();! m9 k" f- ]/ o' P" U& _" L
CUPnPImplWinServ();
6 x- X3 V% b( ~+ T3 B
9 {+ A# W! L% W9 G# o W9 a- E5 W. y9 ~ q6 o# L
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }8 ]3 S. `0 u+ c2 }
virtual void StopAsyncFind();
3 N+ [9 o8 Z5 q! H( ^6 U virtual void DeletePorts();
; t& l- M* r% c* z/ S5 K6 O5 g virtual bool IsReady();7 f- F( D k1 N3 N" F
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }$ U# H' r/ k/ q0 d$ C1 A) Z
0 C; c4 M2 C+ M; e/ r% l6 E9 x0 ~5 ^% A! v6 ~+ D, ~7 n. s
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
4 f G6 b7 v' V // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
; w; a9 o9 N) ` virtual bool CheckAndRefresh() { return false; };
6 y6 }8 n. s. g O" S/ G1 `- B, j# ?( m. ]# Z# s3 X
4 Q0 l6 k3 I; I4 A( Tprotected:2 X" s @" |3 T, _9 ]9 o$ r
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
G2 c8 E! T' A5 k' [$ H void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);4 C4 S# j7 K' g3 n. _- M
void RemoveDevice(CComBSTR bsUDN);0 k4 I% M7 G! z c7 \" f
bool OnSearchComplete();9 b H& s& H C5 q% P
void Init();# m) h7 c' E! J o) d
4 ~; [9 L9 _; {$ y% d s
* z! Q2 Q% c: A9 x5 @
inline bool IsAsyncFindRunning()
0 D# V F* \% ?* T {
' B$ ?9 n- j" H; W2 u2 b if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )1 n/ C# l, [" t5 Q: \4 v/ @' ?$ L
{
+ L, ~- N$ @* g7 j. q* v7 K m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );1 b0 j2 ]7 v! \" S1 k
m_bAsyncFindRunning = false;$ v# G+ p$ r6 N3 s3 s/ N
}" G1 j2 R+ o3 _% u
MSG msg;: X: S: T! [" P4 D
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )- ^3 B2 M" @0 k7 S. e6 e& ?
{! A& m$ y/ Y0 d, E* a
TranslateMessage( &msg );8 H* Z! A. V+ r W% L/ h) o( h: l
DispatchMessage( &msg );* g5 d% Z( ?; W, e: E8 O
}
' Y) X; p3 D. V return m_bAsyncFindRunning;% K% { u+ ~3 n! m) G( L7 X
}8 Y* c0 b! K" w) _. K
4 }0 @1 e+ W; M# R1 S& H& {
; L5 m- l( K7 e" _/ V# R
TRISTATE m_bUPnPDeviceConnected;
2 p8 \8 |) g* w) C2 C7 O
/ ?: {# A2 B' M0 F. ~' J
7 R, q. m9 k. D3 F4 B// Implementation8 i: p9 N0 M" g% }( V. X
// API functions y! F9 q, S& z* a L
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
( @: t, z9 E- W; B SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
, T; v/ }2 t/ a! p4 X& R+ `$ W5 u1 |' P BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
0 G/ e" i7 O' Q; G; |, ` BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);2 \; K! Z( p) O$ B; {) A1 t
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
; [! ]& q: j: G8 I% j, ^: s BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
: L" \# L* m; ]; ~6 v0 s, |; o7 F6 x; Q
% b5 K9 _* K$ J) e; ?: F$ x4 e TGetBestInterface m_pfGetBestInterface;
7 {$ {$ M. ^1 H! s' u9 s TGetIpAddrTable m_pfGetIpAddrTable;; x9 ^8 ^# M9 K8 A. w( I
TGetIfEntry m_pfGetIfEntry;0 ~( `; B, I- {
& o9 Y$ b" W3 M. W
1 p1 {; e: }& U( O static FinderPointer CreateFinderInstance();
% A' A+ ~4 b# i' _* @ struct FindDevice : std::unary_function< DevicePointer, bool >
( g1 P/ ^7 y7 \& [ {# d- {! w% [& q V. m$ `- J
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}: D4 y0 h- y: C" V) k" ~9 Z# L
result_type operator()(argument_type device) const
( m) ~2 ?6 g- H3 V- s5 f {$ L9 [" \8 x! c0 ~- u! d1 E
CComBSTR deviceName;
! d- A, M- e4 {7 V( a Z; u HRESULT hr = device->get_UniqueDeviceName( &deviceName );& X) o* _0 o) P# ], ~6 N" o, m
; z1 D& C5 h. b% n3 v2 O7 ]
- c0 V. h" f6 C* N5 E if ( FAILED( hr ) )
6 _* l: X9 Y' t# F return UPnPMessage( hr ), false;
: h- T0 T8 j5 p7 m5 }) ^9 m8 c3 Q" F" \: X
* t! N+ e: \9 w6 A' [ return wcscmp( deviceName.m_str, m_udn ) == 0;, m0 L* }5 \. g0 e+ r! T9 V
}( z, s( i: D" `" R* k5 v
CComBSTR m_udn;
4 b7 w+ t" S* o" j5 |# B };
4 \& j F8 C, e( O+ ? # H( n- r2 l4 v# I4 m v2 F) B
void ProcessAsyncFind(CComBSTR bsSearchType);" n3 Z( s' L6 Z& G0 z
HRESULT GetDeviceServices(DevicePointer pDevice); w) q, b/ K2 T' i
void StartPortMapping();
6 T9 k6 J ^, V6 C2 r HRESULT MapPort(const ServicePointer& service);: o# t4 I% a% f
void DeleteExistingPortMappings(ServicePointer pService);. ?3 W: j' ^, o! c5 T
void CreatePortMappings(ServicePointer pService);
. J* `# y2 b/ t2 `2 s HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
- n; G4 X/ y, R" e HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
& V7 v' L5 m/ a. p& t& T; g) _ LPCTSTR pszInArgString, CString& strResult);7 }; `2 F4 l N5 i% u; y
void StopUPnPService();* ]' \( p, r2 Q* Y# q
- I! n* e s" L5 Z/ [% C( r; r7 V. Q3 i2 }; |
// Utility functions! O- h% }5 F* t9 G. A+ u
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);. H( B% U( X: O2 f" I' H
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);8 o' n& c1 s! Y5 ~3 ?
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs); S2 V( c: [$ o- @1 b9 A6 y3 R% [
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);9 o \+ B- {5 q9 Y9 y2 ?4 x
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);+ n7 w3 |" D& A: V
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);, K9 s; o" Q2 m
CString GetLocalRoutableIP(ServicePointer pService);# ^! n. @3 T! G6 B5 m5 _
9 b# p9 H: g) Y
! c# ^& E# C! a j$ m! j7 n// Private members
, ~9 W0 ]& N* j" U: h Lprivate:
* ^& L3 |4 x0 r) t0 i DWORD m_tLastEvent; // When the last event was received? d- A& l8 q. P0 Y, l* E
std::vector< DevicePointer > m_pDevices;
* t/ i" E6 v5 K- P std::vector< ServicePointer > m_pServices;
1 v$ U7 z+ L# b, Y FinderPointer m_pDeviceFinder;' t2 N2 k2 ^) ~ D( e) f# i
DeviceFinderCallback m_pDeviceFinderCallback;
" X$ |0 @4 P" c: [+ S7 |# b' h ServiceCallback m_pServiceCallback;& I: w. W z0 A7 a; P
! M. g$ I- V8 i e" ]/ W
$ I4 f7 u) p3 S3 @. T+ v LONG m_nAsyncFindHandle;
, E! ~+ ~( J8 w' A bool m_bCOM;4 P3 I7 j# O* O* m
bool m_bPortIsFree;
% o& Z2 B3 U: T+ X) p: w CString m_sLocalIP;
. p4 E" {% |- n/ f9 u! o0 b: | CString m_sExternalIP;
6 n$ ^% e9 e N0 A8 C3 M bool m_bADSL; // Is the device ADSL?: b# w2 R Q- h& x8 _( L
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?' J4 ?4 e [$ E: ]. G* o3 ?
bool m_bInited;
, s s: I7 o1 H" b$ z3 [3 H5 p bool m_bAsyncFindRunning;; @+ }. E7 f- Y3 S0 L" ^' r
HMODULE m_hADVAPI32_DLL;
. j* w' E% `5 y0 {# @0 ` HMODULE m_hIPHLPAPI_DLL;! {8 G: x* r2 g" D4 w. ^; c
bool m_bSecondTry;& c* [5 E) d4 K5 J
bool m_bServiceStartedByEmule;: L2 K/ R& d$ d- z4 z, ~ P
bool m_bDisableWANIPSetup;9 S5 b( L' w8 r
bool m_bDisableWANPPPSetup;7 A* |$ o4 C3 |' |
. l2 q2 D& _8 ]8 ]! }0 g. i! {8 C" n5 j; \
};$ F( e+ d- Q1 x) y8 i4 ^
3 N D# _' w- n( g- p& |" H
7 `1 F1 W4 m) y3 T" G; b9 \// DeviceFinder Callback1 L z, R( R% |
class CDeviceFinderCallback+ o% |; E3 y; K( G1 N& X
: public IUPnPDeviceFinderCallback5 m$ s2 e3 n: r, y- s0 v
{2 m' g; {7 q- b3 G) c* q
public:: v, S: h& f/ n7 o3 J
CDeviceFinderCallback(CUPnPImplWinServ& instance)
4 ?7 t5 ]) S6 v1 `, x* i : m_instance( instance )& H( b( E9 Q% x& W+ N. ^
{ m_lRefCount = 0; }$ u. I f. O. k& t4 x, h
8 o( z# P2 B* U. b( M% @$ V
4 l" C. t) A1 N1 @% _4 E0 H STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
1 k9 }% G/ U& N% Z STDMETHODIMP_(ULONG) AddRef();
' m9 F1 Q4 s: z: f( b% b9 r) Q# O2 j STDMETHODIMP_(ULONG) Release(); S4 M x. M/ l( k* T
0 i$ n+ ]& g- D2 \1 p4 ^: a3 N" j2 Q0 D& o4 W8 i1 J, E6 R
// implementation* u# t: T9 W- L* v. r% S
private:
, h7 i8 s$ A) w' s) J, c8 x HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
7 _! A/ a: Y& Z& L9 b HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
7 j- U. I* D3 G, ?( @ HRESULT __stdcall SearchComplete(LONG nFindData);
+ r8 Q' O, Q6 S9 r5 n j& g x( v& z4 |
4 `) @( r- j0 E& J3 v) B
private:
# H, ^' \/ z3 q CUPnPImplWinServ& m_instance;
8 u% X1 J4 C# w( S* R LONG m_lRefCount;5 h7 C. d! {' u! L5 T, b
};
# P, a. m! o& a
7 J" t+ H( @0 z+ m1 y! d, D
2 ?2 |7 G2 c; i// Service Callback
$ s9 g. w! A' J5 tclass CServiceCallback9 D' n( F2 Z! N* X8 M4 x9 P
: public IUPnPServiceCallback, O6 m' O' @1 G" f- v' E( q
{$ q( k! A" _) C2 q
public:- E* B0 X' d* L, ?; O9 C7 o& U
CServiceCallback(CUPnPImplWinServ& instance)1 r( T. ?# k' E; G4 ~ D2 r' k, ^
: m_instance( instance )* E4 }8 |6 k3 Z5 P8 F; m; l" ^
{ m_lRefCount = 0; }
. H; y* @1 |$ G. P* x ( N2 X* H" F& X6 I# h' r
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);2 W" R, A9 j! g ~' c
STDMETHODIMP_(ULONG) AddRef();$ l; f# {' i0 h
STDMETHODIMP_(ULONG) Release();; Y" ]3 c5 d1 f9 I) F
% r& G7 J# B; ?- C8 U5 o6 R& Y
0 }( g! r9 E& z& x4 K7 c7 v$ W
// implementation
/ j. n& U, d4 l/ B& [( ^8 N; Q7 hprivate:7 U+ H% o4 e! U' l' P7 O2 e6 W
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
; m$ I- W6 W& T$ E HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService); e1 p" q; k' a) \8 a9 Z
7 R4 V4 y$ Y7 G4 V0 x4 p
/ S1 ]- w) y9 X9 I9 D) C+ Oprivate:/ ~& m9 n2 T# A/ A
CUPnPImplWinServ& m_instance;! K; v ], Y. W! W( I5 S
LONG m_lRefCount;4 w% v1 ~' ]- O
};1 \: ^" F/ a! v ^- l; P+ B8 ~
1 m, c6 D" K8 J8 ^: B6 n
0 { I3 t5 u& S! x3 E/ l
/////////////////////////////////////////////////$ J. f3 K' `% a- N5 L
; t5 \; f5 a2 z% F1 c4 {: ~7 _8 Y* e3 t! k/ x o0 p" v
使用时只需要使用抽象类的接口。
- F2 c. r- e) g: d% f# g" s/ HCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
+ \ Q0 a* `; |, p3 VCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.& F, \0 p0 V& p Y5 F) t
CUPnPImpl::StopAsyncFind停止设备查找.3 N3 m# R0 P6 @0 i1 M9 l) Z
CUPnPImpl::DeletePorts删除端口映射. |
|