|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,0 K# R) P5 v/ \" ^( a! d
8 i Y. V& u* m, ?: S E
: o: l# b5 P- |7 }& i///////////////////////////////////////////$ j8 H& T8 V: W( C8 R3 n
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
- p7 R: }) O. L$ H9 t+ @; {. l4 b8 s$ t# E8 q1 X
( y- S2 o, V5 u8 t f+ I% G#pragma once6 Z4 o4 S% T1 ?, u
#include <exception>, H: H/ A6 S% l( E! O1 J. O
* V- P; x) w5 e! y J: d8 P) q7 K0 }& V& H' V5 Y$ z9 p
enum TRISTATE{
1 g! Y+ W8 Z6 r; m TRIS_FALSE,
/ P8 L8 E* I* [8 d- { TRIS_UNKNOWN,
; [" F+ c$ s, V, W6 p! U TRIS_TRUE/ a$ ^$ y5 U3 ?( s; c$ k. |3 l
};- {1 X9 F: o" S' P0 y Q
$ i5 Q D) ^# G
0 {6 Q$ V! ]6 _- B: b1 n9 Eenum UPNP_IMPLEMENTATION{# o% k+ C5 `! E; g: _0 e3 G
UPNP_IMPL_WINDOWSERVICE = 0,
. Q, q6 Z& o0 S5 [% S UPNP_IMPL_MINIUPNPLIB,& W1 ?3 i& t) V
UPNP_IMPL_NONE /*last*/
- e0 k/ J4 }5 n# s) b};- B, M; y* S% U) j; A8 T
: |7 z- T# l+ [3 }# Z# E
0 e. Q n/ u, y! S4 u8 h
8 F+ Y6 @2 O! A( Q# |4 U/ M
9 f0 \. j$ h7 x( Y
class CUPnPImpl. V" G5 Y8 N# q {% o' n
{
) i& I' {) k ~! P' {3 Npublic:; P. G" z" H# v7 v `% E
CUPnPImpl();
8 e c7 @* i1 l$ g virtual ~CUPnPImpl();
) d" U" V5 _( b* G1 u; P( d% ^ struct UPnPError : std::exception {};
' X- n$ ` L) Q* I6 w9 Y7 A" I9 s enum {7 G0 A0 J: ~# a* q& }0 q& S& I- e8 U
UPNP_OK,' i5 C, i! M/ Z. Z! |6 n
UPNP_FAILED,
9 ?/ |1 D% M& F$ } UPNP_TIMEOUT
+ G3 g9 c+ t7 C( O! [ B; q };3 \& H2 w+ f7 T k+ P" T
8 d- u. a% ]8 C3 {; z5 O" w2 W5 X% \$ J# \+ p, P2 s
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;' Z9 G( P8 R, q+ i7 F
virtual bool CheckAndRefresh() = 0;$ U1 n# ?9 T. d- r8 @/ S! G( z
virtual void StopAsyncFind() = 0;
2 ~7 b+ F" i3 k( P' l8 t1 ]0 |6 b virtual void DeletePorts() = 0;/ F* D9 X! L! F+ `
virtual bool IsReady() = 0;0 _: [0 t6 w! Z* @5 C8 K9 u5 O6 W
virtual int GetImplementationID() = 0;
; w" p$ f+ o# O7 E% r
$ z/ K, R ^" \( O void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
. ~4 e9 z8 q+ {7 H+ ]! W9 f# q- p, i3 D/ o5 Y+ _9 u( n
; V( r( s6 c0 f) J- s void SetMessageOnResult(HWND hWindow, UINT nMessageID);, o; V" \1 p) L( @: B5 q6 r
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
) r0 l5 Q9 D% M+ ~# Q2 |6 @+ U- J5 I uint16 GetUsedTCPPort() { return m_nTCPPort; }: X% D# i$ o9 p( c; |
uint16 GetUsedUDPPort() { return m_nUDPPort; }
+ Q3 o& \! _ H( R9 A" T4 `: s4 E X7 O' ~7 k# v: T/ I s5 m1 G: e
' G) ?3 _' V/ ], `: z% ` w// Implementation* n/ D o7 E, R: `9 P! m# q `: \+ {
protected:
; {; l1 _& u( x volatile TRISTATE m_bUPnPPortsForwarded;) f4 j( m) N" ^; h; X5 l% S5 S
void SendResultMessage();$ p& z( Q5 @! T6 V, A
uint16 m_nUDPPort;
( R7 d3 o) j5 b o% Z6 L uint16 m_nTCPPort;
5 @! I% k; W+ U uint16 m_nTCPWebPort;$ ]& R. H$ N- w* }8 A
bool m_bCheckAndRefresh;6 U+ Z/ V- ~: E7 c% V+ u, j- Z' g3 o" M, j
8 E$ _9 g' v# `* \* e& {
, f1 P' i' J: v p7 Gprivate:
0 T& P+ q% C% y; q. i! P( L HWND m_hResultMessageWindow;& f% K! ~( l2 J
UINT m_nResultMessageID;
3 G: v v- D& s% f' ~4 p5 O: B% H* D6 t
5 K3 c7 I3 K; ]
};2 U* o- i6 n3 j1 s
O5 r: p6 C" z7 h3 j$ ]
a: n, y( Q6 c; R2 k// Dummy Implementation to be used when no other implementation is available0 l6 H1 g/ C# g# \: Q
class CUPnPImplNone: public CUPnPImpl
1 C2 c& F$ d" @- S3 x/ p{
2 d S; h( z) fpublic:
' S5 }1 ?- z- i' j virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
( J# c2 }- f3 H: Q5 W virtual bool CheckAndRefresh() { return false; }
9 Y# i7 z- t& o/ q/ H; Y, W g virtual void StopAsyncFind() { }3 ~6 }' \0 T2 m1 c. Z" {# c; ^
virtual void DeletePorts() { }
4 f2 N+ r+ g2 R6 F1 t virtual bool IsReady() { return false; }
# i( Y$ y* U% D; U3 F( a, r virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
7 S& }; ?- {1 z};
' R7 @" v z9 M0 `8 K
" [$ `8 G5 K9 Y) ^" W* I" q+ W
3 A; X: ], q$ y" R4 E* c* o6 ` E/////////////////////////////////////9 Y @/ x$ b$ b- p; y
//下面是使用windows操作系统自带的UPNP功能的子类0 Q$ l, g5 |. B8 @) i
$ e$ R U; s: P* }% b# K9 |
$ M& ], V! C5 W8 v6 n/ C# F7 u
#pragma once; W$ Q, H+ e# p& \: _5 Y# D8 H
#pragma warning( disable: 4355 )0 @2 ?2 t/ q, d0 ?! f) \
5 {. K6 Z1 \' B0 r
1 g+ ?2 T8 S, L* P" }! W#include "UPnPImpl.h" D& w$ y. n; k2 M( E' v
#include <upnp.h>
& v# U6 i) [2 {+ n" c#include <iphlpapi.h>
4 {& j k' j9 }' q3 z2 u* T#include <comdef.h>
( D7 w( U7 ~# {9 d2 F% F#include <winsvc.h>
7 U U) |; S, R% h( x( U% u1 C5 p, z9 ] L' _7 n' T
4 j- Z8 K! V! |. {2 J- }# x& E+ ]
#include <vector>0 ]2 ]) e! u' \/ }# C2 V
#include <exception>
$ B0 R4 N! N. U. Q# Y#include <functional>
' [8 a8 j& u0 _$ K7 `" d
; b' N/ E4 E+ o# e4 V
* z {! z, t) I# ?- K2 G
( E$ r" p1 T5 J; r0 L T3 |$ M& E# s+ I/ z6 \7 s
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
# z$ M g+ m5 p, Ytypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;: T3 k: X4 l1 ]
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;& S" ]3 u& J* i) I7 r2 }
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
& d) l, q" \: ^7 Wtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;# r! L3 y2 X8 ?2 d2 d: a
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
* D2 E `* x a! q7 g9 ]typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;# v+ H% h ?1 D, T4 ~) H) @
$ O2 G* |- C. w# W; \4 W
: F/ o' o+ e( Xtypedef DWORD (WINAPI* TGetBestInterface) (3 [* C2 ]9 @' d0 m+ E2 }+ t. }
IPAddr dwDestAddr,
# F3 ]" \5 c- m; s$ t% {, n$ f$ Z PDWORD pdwBestIfIndex
+ D- O5 V6 C @% x);
6 a% y& _4 z0 i6 U' z; l
8 f2 C7 m& Y6 f5 P9 w7 z B$ e0 p4 n- q0 P; s- a" C
typedef DWORD (WINAPI* TGetIpAddrTable) (5 O0 q/ M$ ]& r0 G/ I% z4 J. Q
PMIB_IPADDRTABLE pIpAddrTable,
9 n. H, q, }3 {/ Y PULONG pdwSize,
! A1 [0 c% G* z) ^; o& S' R2 J* p BOOL bOrder
6 [8 n/ U6 R2 g+ Z* ^, \3 t! e);, R, L) {: Y9 ?) A% d, H; Y0 I- |- A
$ k$ _% }+ Y, {$ y$ c" Z( A' a% {2 z. F. p1 a* }% X
typedef DWORD (WINAPI* TGetIfEntry) (+ o; _$ d) \$ O9 U" r2 M
PMIB_IFROW pIfRow0 M+ Q0 M( B3 g; H. L
);
$ t8 z- _( c3 V/ }
: @+ j1 `2 [7 W; [9 \0 U k5 O3 Y4 `$ y0 q
CString translateUPnPResult(HRESULT hr);
# `. _7 g# f: R+ x3 Q7 cHRESULT UPnPMessage(HRESULT hr);$ X% G9 d: I' [/ |' Y0 `3 V
) U4 n0 V* Y# q" a$ _/ V
4 b6 v) s6 t2 w' F( A; \1 @class CUPnPImplWinServ: public CUPnPImpl* F* p+ M% \3 N [1 m
{
- h$ a# o, r; j friend class CDeviceFinderCallback;5 o& F( V( b) f2 I* N" ]+ Q
friend class CServiceCallback;
- s" q0 ]- ~& a* C6 ?% S( S6 x: s// Construction
* |7 E8 x N5 Y2 \public:; P4 E. J+ E$ _5 [
virtual ~CUPnPImplWinServ();0 Q2 ?0 C+ ?+ T5 W; D
CUPnPImplWinServ();2 H r+ [* V2 C' ^$ K8 G
9 j, k7 p$ h4 U8 i4 Z/ h* A' ]* p8 y2 `+ o
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
8 ]3 ]" P, _& O9 y. u$ d2 }3 \4 B9 ]* I virtual void StopAsyncFind();4 B5 |/ V" ^2 ]% g- @
virtual void DeletePorts(); O7 d8 B& P, x% V& t9 c2 @ U
virtual bool IsReady();
' K- h' W6 r: M* W0 } virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }- b9 { v5 `! S2 r S' H) O; P
/ y) b3 B$ g5 ], w+ N
8 j: B8 u+ p# `2 O
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
' S7 A o" e) r // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later3 J" d: v; n c6 @- ]
virtual bool CheckAndRefresh() { return false; };9 _; t7 z( Y3 r" {$ G
9 n3 _( d5 C. [5 i5 P: Q; a% m
; i! J" J1 \; [% p
protected:0 A$ X& V$ W( L _4 z
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry); g. f" H5 Q0 h0 O4 [
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
' m* \: }4 Y9 A; L7 C7 A void RemoveDevice(CComBSTR bsUDN);4 r3 M1 a( g- z% C
bool OnSearchComplete();4 b1 X+ o0 K: F' V3 M
void Init();
& k1 W0 F4 G* }& e3 b2 L# L8 e7 R; }: K( n4 g
( j9 \: u- B5 o: ?! H
inline bool IsAsyncFindRunning() 1 t5 ^, ^9 }; @+ O/ h- l
{# j, W c" }3 m6 e" T
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
, b( H. N' U( e7 [4 Q o4 y& F {7 ?$ d W: ?3 Q8 h) z
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );/ v9 S$ v1 Q* G
m_bAsyncFindRunning = false;- C* O+ |# G1 A+ O. B
}
" A0 T7 \7 R5 N5 L MSG msg;
2 s( t3 H) H7 j, n- Y3 ?# q- S while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
, L8 }. a a4 _$ ?# n5 G3 z5 h {# ~$ T+ k: P+ ?2 j
TranslateMessage( &msg );
# d+ Q9 e+ A* R DispatchMessage( &msg );4 `$ \6 D: J* A5 y3 D
}9 w- E8 m6 v9 S" ^6 V; W, k, d
return m_bAsyncFindRunning;
2 p0 ]0 S7 i9 @$ s- o. \; p }4 v8 v- [9 A5 W) Q$ ?6 B1 m
8 [& y" i7 [4 [8 K0 y$ \
. ?/ K" k+ q5 R6 j+ L0 p; S0 Y
TRISTATE m_bUPnPDeviceConnected;- d l( T/ B% m. y d3 W [2 `6 e; m
* ~$ F. c/ ?+ z& q
5 l9 @1 N* ]# _# b8 ~# t# K' [7 c6 v// Implementation) Z- E, y9 {8 d" X9 ?, y( b
// API functions
7 I+ u: g" _( v* k" C) ] SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
9 X5 c5 M! D0 [2 B/ W5 G SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);( }# i3 e0 f; r9 e' I1 U
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);5 i+ l: P* f+ d# D: M& e
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
0 Y0 R+ _% K* j! L BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
2 ^# c+ l0 i! A( J( P: w) F BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
3 F, a& G( C v! X9 X% L' v1 l: V! T, u% T; R: N
2 {- E9 X- B+ i) D& x1 l TGetBestInterface m_pfGetBestInterface;
- R# U! d. I. n4 s3 l# h TGetIpAddrTable m_pfGetIpAddrTable;1 Z; a2 v0 c' A v6 f
TGetIfEntry m_pfGetIfEntry;! {3 @. H9 H: d, T4 G# N1 D
* t2 {( \' B# L1 }) R
, a$ R ~+ J6 W. H% O4 u2 s; D static FinderPointer CreateFinderInstance();
( e- J+ }* A$ d4 h9 W" a& D struct FindDevice : std::unary_function< DevicePointer, bool >' X% G0 }. F" A* p& p5 y) M6 _9 O
{% q8 J- M0 H5 s: }& O' R
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
9 ^" \3 g1 v! N: E" r result_type operator()(argument_type device) const
/ y, J1 [1 x U, W {
: W: \6 k* t8 X CComBSTR deviceName;
& X" F# m/ [+ ~% b% N. u HRESULT hr = device->get_UniqueDeviceName( &deviceName );
( J* R' A j# U u" A
, H4 i" ]" Q; s+ b+ g# M0 G' V9 M B) v" m! C8 w
if ( FAILED( hr ) )
. b- P3 c4 j( |& [- A" u return UPnPMessage( hr ), false;
0 G' d9 Q) ]) P8 K" i1 {
% k7 K8 n8 A3 ?) |$ Q
( c. i% e; n; r# ?' I3 Y* W* s$ F return wcscmp( deviceName.m_str, m_udn ) == 0;' f* W4 h- h; \1 y9 F
}3 k' z& {! K/ P
CComBSTR m_udn;
8 Z* z1 g v2 }! X8 s };: \/ X8 h# @0 A! e
; I1 }3 |9 B& n- ]4 o1 e+ ]
void ProcessAsyncFind(CComBSTR bsSearchType);
" s* m8 m, q0 M$ d- `/ e$ F HRESULT GetDeviceServices(DevicePointer pDevice);5 d% z" b7 A! D6 Q4 {
void StartPortMapping();3 f( l6 F9 K; g) V
HRESULT MapPort(const ServicePointer& service);
: g- }& D! B% c) Y3 ]; V5 Q" y void DeleteExistingPortMappings(ServicePointer pService);
& u2 g) m2 h1 L" H void CreatePortMappings(ServicePointer pService);
2 D3 y* a* b% p! v, e9 w HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
+ r1 u' {8 W7 b' t HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 6 f6 k& {" U* m6 O6 b
LPCTSTR pszInArgString, CString& strResult);2 f0 t' l {2 u1 C l# Z
void StopUPnPService();
% z# R3 B. Q" c* r6 K2 X
5 f" d# P' ] Q+ z3 u( {! o! y# t0 [$ q7 p7 p( g8 i3 i% O! e: k
// Utility functions
' m6 B" O1 G6 |$ D3 z2 c0 W3 ] HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);2 p. c4 ~3 D9 ?7 X* a0 o
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
4 a% {. ]8 E. V! d& g4 j INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);% X' f( O( m4 C* d9 M+ G. r) L
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);/ c( f X9 X; v) }- M
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);" ~, {! T$ p2 U4 \1 |9 c# e8 H
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
) A* P. k7 W$ U+ W6 T6 Q8 } CString GetLocalRoutableIP(ServicePointer pService);4 c- d* L1 {3 z5 G3 J+ ?0 ]2 T& G
) F* Z. B3 s9 h1 V/ F4 s
( t0 q) s5 X+ W" \& X// Private members
, S* Q0 D% j6 J4 W7 S+ ?private:9 ~' r4 K8 O/ n$ z' h/ Z* q7 G( W
DWORD m_tLastEvent; // When the last event was received?( |1 w: y0 K3 A6 l3 j3 [6 Q0 i& q9 _
std::vector< DevicePointer > m_pDevices;
; k5 }9 Z+ x/ T* A6 W std::vector< ServicePointer > m_pServices;
+ W# X) H- r/ U- x FinderPointer m_pDeviceFinder;: O' t1 y. X8 z# H7 L3 h1 H
DeviceFinderCallback m_pDeviceFinderCallback;5 ^, W. A4 F2 P7 q. r
ServiceCallback m_pServiceCallback;
, m g4 `4 S, n1 m: p4 T/ _( n8 r2 v% D" {- k G) E2 Q- _; Y
% A7 o$ A) ?& X( t LONG m_nAsyncFindHandle;9 d$ V& H6 m0 L/ S
bool m_bCOM;
7 C# s4 {# P4 Y0 h5 i( {6 D: m1 \ bool m_bPortIsFree;; E( W0 P8 \( w) S; \% k
CString m_sLocalIP;4 Q b- Q1 H$ G# Q/ ~$ e
CString m_sExternalIP;. C2 k* `( t5 l
bool m_bADSL; // Is the device ADSL?' S; U+ [% f6 B5 I1 n: r |
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?7 r9 \# m% A, d1 Z8 j9 }
bool m_bInited;0 J/ \2 F I, u( v: m
bool m_bAsyncFindRunning;5 K' n, m; a1 F# {7 ~* q; ~ }
HMODULE m_hADVAPI32_DLL;/ e2 c! d( t" }+ Z
HMODULE m_hIPHLPAPI_DLL;
L9 U! q& C" @8 q& Y# J9 U bool m_bSecondTry;
. V( A6 @/ N& F2 H. U bool m_bServiceStartedByEmule;+ ^' g; L6 Y1 i3 A" [7 ~
bool m_bDisableWANIPSetup;
: F" X h( {3 H. G" [; w bool m_bDisableWANPPPSetup;
: w; ~: h5 w# P) L$ m" Y7 G0 s1 {$ S, y0 |3 O6 l: B6 }& l4 v
) W0 o" U5 v' Z; P# U" T1 E- x- j, U};' K% c$ |, I* P C m, G
. ~7 B) H, i1 G! M! x' T
5 H! U5 v6 X. \7 r, w: U: w9 S// DeviceFinder Callback* S0 O+ a2 Q6 @- h2 W% r0 W5 ]
class CDeviceFinderCallback
; m" x9 A- u6 r4 x8 M& S : public IUPnPDeviceFinderCallback1 f# @ F$ ?' o3 M+ f" C
{
9 Q5 [& w+ y$ E0 Z: o& Apublic:
7 U3 b8 O! o2 m1 s* U2 U: V CDeviceFinderCallback(CUPnPImplWinServ& instance)) I8 ~: G# A8 i4 H1 b" P/ p- b
: m_instance( instance ): h x# Q% m. F" ^4 ?. u: }' g6 K
{ m_lRefCount = 0; }1 T; e& F, W* \: ^, D# G) y
/ m8 Q& S+ |" I; \( K% v9 F/ Q
- e. c+ _, H ?- h4 M7 C* ? STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);8 q/ V; y. q* q2 p7 P" [
STDMETHODIMP_(ULONG) AddRef();
% h/ q$ V# r8 c: Q$ j STDMETHODIMP_(ULONG) Release();
6 v; E/ I1 j- [- E
- v7 [# |$ k6 }' Q% w5 |/ O/ Y3 Q2 A4 L( J3 U3 Q& @
// implementation) ^: p7 c8 D0 N+ r1 S
private:
* ?1 \7 I! S- Q1 A' L8 ?: j HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);8 X( Y3 S" z" Q5 g6 j7 {
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
0 d7 m6 t7 x' U. s w0 A HRESULT __stdcall SearchComplete(LONG nFindData);7 t+ u0 L# a' K1 I& a* |6 u% S* Z! c
1 ?+ `( d6 x+ g1 V
% {* E4 ]8 s' ?9 g, E5 P1 Iprivate:
- J6 P! D& S) M' ? CUPnPImplWinServ& m_instance;
: T' C6 J! m8 s5 ]7 T: Q LONG m_lRefCount;
$ F2 N) A# F) L5 U1 e};$ E' q; l5 m' t0 A$ @
) x0 d, Z, Y% L5 x6 S6 N! |4 j5 E" C& k0 p+ F
// Service Callback
% T7 U6 G1 ~! ?- b5 }# W; y0 Zclass CServiceCallback% V1 R9 V: O2 ~+ N( {
: public IUPnPServiceCallback
# v7 ]& f( @1 {6 E" s. t- \{8 t# ]2 x' s' ~& w
public:) @: N5 V- E* F# j+ s" w
CServiceCallback(CUPnPImplWinServ& instance)- f5 X: k% F' j( _: N2 T
: m_instance( instance )
$ L, U* B. Z; }) y! T2 [2 \ { m_lRefCount = 0; }3 o/ P) r' p2 y5 Z5 G4 |
& F! J. [, o0 L |/ ?0 O STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
3 E4 l- B) t x' k" r1 |$ K STDMETHODIMP_(ULONG) AddRef();
) [+ Z# N+ ?4 {8 B" g) u, h STDMETHODIMP_(ULONG) Release();
' o" ~# v. m6 u/ q; i: R% d4 R5 S6 r- R
4 ^) _% }7 K6 \* Z" N1 Z3 d1 z, ~0 J+ O8 S
// implementation
$ @1 Z* A1 m6 h/ O* c( bprivate:
% V: L0 `9 h4 v; n, `# }2 L HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
3 U3 `! q0 ?. w0 y7 d$ w HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);- [. }) I" H% W5 N8 R$ D; J: n
7 O: x4 v% J, Q) C% G- P
2 C2 U: l( k5 S, k" |! T! Eprivate:5 n$ s a0 h6 p4 ^
CUPnPImplWinServ& m_instance;4 x+ m+ |: p ^3 L
LONG m_lRefCount;
8 x; r7 V, j# O% `, G};, _. E' e4 b/ U
! e4 |9 P& U. V7 J8 ?
3 h0 ^* N y& |: C7 d2 ~/////////////////////////////////////////////////
: T1 `7 v& L: T' p2 H& R
/ c h( S6 M0 O7 T" f+ F7 M# e
& ^3 _* q% i* a( k使用时只需要使用抽象类的接口。
4 B* o8 q; @( d; [CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.1 |6 n; F0 |9 |6 h
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
/ Q' ]5 ?4 u' A* L7 `. N% mCUPnPImpl::StopAsyncFind停止设备查找.
2 B- r: E! u4 v; |3 b9 P/ SCUPnPImpl::DeletePorts删除端口映射. |
|