|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
4 W7 P( v+ ]9 L$ w# }9 q% s7 d% V( m p6 a0 M- M0 l* Q
8 S) m! E) |# g( h( n" z; w///////////////////////////////////////////
3 f, W$ ?* {& E//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.6 A' ^2 f: }( Z7 P# y
% X% F6 f# t. W8 U, i: k! L. Y" p% ? s+ x5 Y. f
#pragma once- ^* T8 d! D8 d4 D7 D ~ p; ~
#include <exception>
0 j! u) @5 o* N Q
. A& ? w$ V3 ^
2 M1 `1 A. B0 }0 X enum TRISTATE{; h5 _6 ^; a& c: T4 M0 ~
TRIS_FALSE,% r u3 a/ R- j) |% e, K
TRIS_UNKNOWN,
- f5 {; v+ Z# A0 i2 \ TRIS_TRUE
! H% k% C% }2 j/ v$ u1 Y};' A0 N' Z @8 s! G6 b
# C1 Q) }1 y# M% _
* ^( s; n6 k0 j* `; L6 Z8 X# denum UPNP_IMPLEMENTATION{
2 M P# ~+ K+ S: l/ V UPNP_IMPL_WINDOWSERVICE = 0, F- ]; B) w1 d% j2 V
UPNP_IMPL_MINIUPNPLIB,/ A$ R2 H! e' X2 P
UPNP_IMPL_NONE /*last*/6 I5 t' R+ \/ t7 {
};6 l1 `8 @0 I% E; k* r. w9 E7 M
% z- x2 c+ ~5 }1 l" }2 h) n
, K0 B# p) \7 R7 f- ^ w& Q2 B# J0 K1 g6 E+ P3 M; r) c9 i
. G! V% \5 }5 ~) ~/ Qclass CUPnPImpl9 D1 Q! Z4 T! u" E9 O: F& ?8 O
{
4 i6 i& i. ?# F) Rpublic:
1 l; \- _% y) ?8 I. W CUPnPImpl();6 Z H+ z- r- T$ v1 w) _ r3 d4 T. `7 \
virtual ~CUPnPImpl();
; b0 s7 N9 a8 N& D; \* _: R, w- u. ~ struct UPnPError : std::exception {};: N5 Y+ R4 n2 j* q* h, i6 O( v1 K8 ?
enum {
/ c, H t& q0 ^3 q; N5 g UPNP_OK,6 k$ W2 z _- c, k
UPNP_FAILED,6 |* n) W% }0 }
UPNP_TIMEOUT
! Y+ M" @$ [1 \8 d9 g! q( j };
- H7 M' O+ _+ [# v% R* Y' w/ V; @6 e; D, C5 y/ A. O; B
" P- I' L9 {. F4 H) W q virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
9 s# T3 [& P6 Q2 h; L0 o2 N. E virtual bool CheckAndRefresh() = 0;' {4 |- J S5 X$ [- v
virtual void StopAsyncFind() = 0;
( r, Z4 {. v& q4 _2 u' R virtual void DeletePorts() = 0;
4 }- J7 m* V# m/ f virtual bool IsReady() = 0;" }6 z% g, f6 e. ]+ g
virtual int GetImplementationID() = 0;# L2 b* }) o' z' I0 u M" l2 W
2 }+ W K+ [# j. F |! p7 ~
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping2 h0 P9 n$ M. @0 N* b( f* Y
+ r9 r+ }! W* p* H r$ z9 o5 ?9 e
0 e$ e! j$ T' c7 _" k* V( T* x
void SetMessageOnResult(HWND hWindow, UINT nMessageID);% j3 K- T) K8 X0 ], x* v. I: u
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }' q! p4 |4 G3 I4 q7 n3 P* z" u( v6 H
uint16 GetUsedTCPPort() { return m_nTCPPort; }
( R# f& T w3 m- l& `/ h2 S5 t uint16 GetUsedUDPPort() { return m_nUDPPort; } + u) r2 ?& L9 u
* ]% h. d8 n; s1 G6 J( a+ E
# C/ N0 K% I" P2 y6 l2 A& F% ?4 v// Implementation4 U' G$ z+ @2 O
protected:
( m! n8 g T/ p7 |* v& `3 d5 l volatile TRISTATE m_bUPnPPortsForwarded;0 M2 G( Q: v) u/ l+ c" W& p5 E
void SendResultMessage();
8 W0 F* N9 ~% I) @- }! J uint16 m_nUDPPort;
8 I) g S3 ~/ [" G, ? W: L uint16 m_nTCPPort;4 H2 X5 a! f7 @# C( d
uint16 m_nTCPWebPort;2 x, K+ \4 u) R; `
bool m_bCheckAndRefresh;
* U+ t+ H8 O9 I
* l5 }& W3 Q! a$ I4 z6 w8 X& n& n+ i2 u; c' g
private:) I4 M+ w: s9 d& ]& R% n
HWND m_hResultMessageWindow;- s$ H" r5 ]1 k1 x' _" p, ?
UINT m_nResultMessageID;
* i! {3 u% _1 {% T2 R; r9 C$ |
( [9 ~8 i9 d8 c! r( I& O1 W$ n: r- n7 Q* S! i; g
};
" D# k- I5 r6 F4 k9 d, G
/ f* J+ o* W, k+ n ^7 a" l4 T! [. i- @- b6 A j% G3 t# B$ S
// Dummy Implementation to be used when no other implementation is available
$ [+ F- A% M( B4 _% K( @- Jclass CUPnPImplNone: public CUPnPImpl
# w8 k3 x; ~1 r; W6 s7 Z8 J( e{2 v3 @! {% s" D! m3 {
public:& [9 |! r. W9 R. h+ H
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
( Y, N D& I5 R# P: _8 f- a2 s4 f' k virtual bool CheckAndRefresh() { return false; }% V- J; E, m1 x. j4 w& T! L- a
virtual void StopAsyncFind() { }
5 Y+ |( z9 ^/ [, } virtual void DeletePorts() { }6 d# F# I3 L, k" J$ ?! }
virtual bool IsReady() { return false; }
/ {) B" q4 a3 p virtual int GetImplementationID() { return UPNP_IMPL_NONE; }, y% m& u% Q! Z" C4 [7 }
};
# p1 B$ n0 c9 O6 Z- k- z+ ?9 Q5 X C$ z# [. D* Z" h. u
1 |: W! ]: n! D. x t( q
/////////////////////////////////////
; L( `5 v) e7 Q0 F- ]9 I//下面是使用windows操作系统自带的UPNP功能的子类
0 w; p8 v* ^) L2 L; e* T& q, X: v& N2 Q6 ^0 H$ V/ Q) X7 H
' w; C0 j" r P) j#pragma once
3 O u' C) {, I+ q8 _( w#pragma warning( disable: 4355 )3 i/ A) P$ p3 w+ B9 p% o
! J# @7 R1 U. Z% |* v1 k' A2 @: S% a5 P2 W4 |" u4 N
#include "UPnPImpl.h"/ L, D5 R+ {: V! f2 q
#include <upnp.h>: V2 r1 u, s1 S' r
#include <iphlpapi.h>, M- N: G2 O: e0 F; J
#include <comdef.h>
& x1 Q% p/ D- ]: O7 L#include <winsvc.h>
8 A2 r7 w" V% [- C
E: w+ G/ h, h0 o* t/ b5 G/ b
: [& t9 l' p) u1 Q3 G( {#include <vector>* W! V: O3 B: f
#include <exception>
! E3 [% z5 d5 Y) z#include <functional>
* }! `6 N# [9 h6 P, X. |4 `0 E7 W. E0 f! }1 C$ g* u
- p. V$ j( l$ { L( w6 S+ H6 d+ ]3 |- F7 H. N$ o5 x! ~: U
" Z. ]7 q* d( f
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;2 {' c" M! }# ]" z8 z
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
. ?# [, N6 [. k, |7 ktypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;; u% I" \- E, k; W6 |
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;+ _. E; m! e" }/ y( X( g: e0 H
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback; y) D, P8 z7 T8 @; `0 S) i
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
% I ]: N* ?; Q" etypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;* I& t7 e" {3 d( Z7 |* r
3 ?- `2 {% @; h( y' \) l# T# _9 F7 @; l# z2 t! A
typedef DWORD (WINAPI* TGetBestInterface) (
h8 \, V4 f/ k( d+ c IPAddr dwDestAddr,
0 p) |0 y7 C+ u. u PDWORD pdwBestIfIndex
, \1 O G0 i% ^, S);( B1 Y2 a# s7 S" N
+ q( }% Z+ p s# m/ b
6 u# J5 _, z' V. f! dtypedef DWORD (WINAPI* TGetIpAddrTable) (
% K$ B; F1 G1 [5 J' L* M PMIB_IPADDRTABLE pIpAddrTable,
5 j' t& D8 C! [; E- c PULONG pdwSize,
5 p! z2 u( k% y5 i: t% ] BOOL bOrder
2 ^/ G) q; M; L* |8 p O* l( J);
# S9 k1 y5 ?( |9 A$ B& b
3 J+ \' `5 {0 i% \, g. y
( P5 ]3 j4 t: A& k. z1 t# w2 ytypedef DWORD (WINAPI* TGetIfEntry) (' G6 q6 k9 x+ E! E
PMIB_IFROW pIfRow
* ~, _( r+ x( O0 W);
8 Q+ c( x/ d# K/ I: v4 F6 X( p0 p/ ~, U- H, C
1 ^4 _1 i$ @9 q7 z2 H
CString translateUPnPResult(HRESULT hr);1 H, u% T7 b' n- t
HRESULT UPnPMessage(HRESULT hr);. V( E. }+ v2 r5 g4 p I
! J Z- S- ^" ~2 N3 u
7 k# i: \% c- k1 hclass CUPnPImplWinServ: public CUPnPImpl1 ? ~8 J8 s" q. \/ F0 f
{
+ B, n8 o$ V8 P& B3 [8 } friend class CDeviceFinderCallback; d* X$ z; m: h" D8 o
friend class CServiceCallback;- S2 d7 E* c& v. J
// Construction
1 N% t* N4 X, Q) q0 Z3 h; Xpublic:
/ e. q' h* M5 g& a0 u5 K: ~1 L virtual ~CUPnPImplWinServ();
* M4 E4 Z) Y* \1 U( Y: s CUPnPImplWinServ();
0 N# D: I4 I8 |3 P* @/ t
/ r+ Y+ L9 g- ]9 }7 B c( r3 }/ h
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
; M ?. ?' i. e$ |! U* e" y- \ virtual void StopAsyncFind();
. T3 E* I, J# {! o7 a; v( _- y virtual void DeletePorts();
+ f" f3 e" O& h; w virtual bool IsReady();
! A0 x- H/ P( k l0 {5 H6 Y virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }2 f2 O2 O% M0 O. g
6 D6 }8 H, v) l0 Q' `2 m
: N6 x9 ^% ^( L. `+ J8 M5 e, G1 s // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
2 o! N' Z! f, p3 N/ u // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
& E# O& ]$ f" R! ? virtual bool CheckAndRefresh() { return false; };1 u7 t8 W. z1 w: [& ?
$ u% [8 K) H8 z3 J# D$ c
( l$ i$ |6 e) j9 o8 F2 f
protected:
/ m8 U! w9 y6 z# D void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
3 `. D9 s& s1 i2 d void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);! Z3 B$ q* n; U4 J! [
void RemoveDevice(CComBSTR bsUDN);
: G2 ^- q# g6 ?/ c9 [ bool OnSearchComplete();
' U, S8 q* X9 b void Init();6 V D V+ G0 w3 v; j" I
8 l' C. a) r9 {. R
) h' I _4 q& ] inline bool IsAsyncFindRunning() " i5 Q' R% s p+ V( d% |( g7 F ]
{/ Z& T& J9 x _. N0 Q
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )! q6 D' K" z; o
{
: a' V" s$ j' P, x' b. O2 C) n m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );9 G0 ^6 Z A: R: C+ f/ |
m_bAsyncFindRunning = false;% J+ i0 H U& D) e
}
8 _0 U/ q' }2 Z1 Q MSG msg;+ [" m' E+ [: {) I; d
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) E5 }& [; l; y: y
{) I0 c6 B! D% A; k& r! [
TranslateMessage( &msg );
! g; U- G, P2 _& h DispatchMessage( &msg );
* G! k. A( L7 C0 H) U }8 X" o' V. h" D; m* y! ]6 q' D, D
return m_bAsyncFindRunning;
' L' R) y3 u; ^3 Y) M0 G7 f( C2 O }8 _ G E- w4 ~( a, V& w. e
1 Q/ ]0 u8 X3 g, A, S# i8 X" s% I5 e) i# P ~
TRISTATE m_bUPnPDeviceConnected;
7 [1 f+ Z$ v! G0 L; Z+ h% C4 v- ]& @% o# M
( Z, g) `3 H1 J/ `0 K: U// Implementation
- s* E! b: f. ~+ g" ~ // API functions
/ F6 Z7 d5 [5 P SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);3 r( c7 _2 z9 O8 d
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
' m0 g o) f, }$ }4 G BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);& b! c" u+ U9 ?3 O7 e4 ~8 h
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);8 M( v. }8 T: }# i8 h: ]& ~
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
' {2 }* d. S, F# @ BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
" y w( z% z) k/ o k) o
) k% p2 `/ l. w# Q; w/ J
" ]: Q& A" f5 ~' T0 ?% y1 u5 P TGetBestInterface m_pfGetBestInterface;
, m5 o$ [. z7 y2 G/ x" C8 N TGetIpAddrTable m_pfGetIpAddrTable;6 l* w- h+ {2 u0 Z) v# R
TGetIfEntry m_pfGetIfEntry;6 L- z( L! q+ r# l; J: W( C' I9 ?
- r L+ z2 V, ~- ]% T+ q8 I: z
/ X2 z* y1 q( V) t8 Y8 W4 ] U static FinderPointer CreateFinderInstance();
* U" I0 h! O: k# h+ T struct FindDevice : std::unary_function< DevicePointer, bool >
( S+ m& M8 f) Y {
+ t& j/ L: Q5 S& c0 z FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
8 a' }5 n8 z3 J2 R( x1 ^0 r result_type operator()(argument_type device) const: c% s, m2 M* F% r6 N, |
{
1 h7 p% Y: J8 q- E+ ` CComBSTR deviceName;; u! _" h H/ I
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
! |5 e, A% _- s1 l/ R: ?! t
2 h2 r8 O4 E' v1 q$ i" D/ T+ \! I% ^
if ( FAILED( hr ) )( s K- Y/ A* ]
return UPnPMessage( hr ), false;
( X: Q5 P2 B1 g. n3 J: t1 E
$ s0 j% J, i0 g. f7 R( a5 `
0 x5 M( S: m5 U& V4 I ]' A$ C return wcscmp( deviceName.m_str, m_udn ) == 0;. b# ?0 T4 y, O# {
}; ]1 s* R1 C7 L& _
CComBSTR m_udn;
/ Z8 R; Q/ f/ ?2 v };
3 s' R |: g( H5 R! x4 h+ Z : P* @4 c9 Z! ~
void ProcessAsyncFind(CComBSTR bsSearchType);
: N% g" t: @7 S% i. k4 ? HRESULT GetDeviceServices(DevicePointer pDevice);; A# ~. z M( n) k* j5 k
void StartPortMapping();
# |6 d0 j. ~ b, Q HRESULT MapPort(const ServicePointer& service);
9 o9 I- C: t% S) ~ l* o void DeleteExistingPortMappings(ServicePointer pService);
7 }+ J$ Z: k4 P# t! \ void CreatePortMappings(ServicePointer pService);6 L$ W. i, L. b2 A, o9 \/ l
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
\- h6 B) P* U HRESULT InvokeAction(ServicePointer pService, CComBSTR action, % b7 Q7 w& h- c+ ?
LPCTSTR pszInArgString, CString& strResult); C) P% R3 K: _( ^- |6 ]
void StopUPnPService();
( g4 b t; Y& r8 q' O- q5 i* D4 N5 L9 z2 n
" c! e% A0 f2 O T+ y0 p
. ^! w _5 S0 I% m3 w2 O // Utility functions
A" J4 C0 i" e# {5 ^3 t HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
4 b4 Y7 `* Y. m M INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);* @! e$ J" r7 R& y
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
! }3 H% ?) N* r2 x! v( H* N& K2 L void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);' Y* r: p2 H) I# {4 e
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
' `3 L+ t: E9 D, L* P$ @ HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
- W- _, y9 [' Q9 d CString GetLocalRoutableIP(ServicePointer pService);
! _* M5 K: b" W+ @7 [9 U6 b/ C; v. \/ c& b6 a1 j9 Y
/ v# g3 ~- g5 _2 c: P, D$ Q7 N// Private members
8 j5 c0 `4 c; {1 z) s( uprivate:
( l$ V7 D3 t% T& E( [1 _ DWORD m_tLastEvent; // When the last event was received?
$ H, ?8 _: ^2 L" u- h: x0 r std::vector< DevicePointer > m_pDevices;+ e5 x! ^8 W) {3 _% \, @, M6 M- c
std::vector< ServicePointer > m_pServices;
: A2 a) C- c! {6 V8 f FinderPointer m_pDeviceFinder;
. }4 e4 V! z% g: m' w+ O DeviceFinderCallback m_pDeviceFinderCallback;1 e7 f8 T9 I4 k# k \1 S
ServiceCallback m_pServiceCallback;
1 J% X* Y1 a5 J1 \1 o: z5 \. u6 p4 q# }
3 y( n" A) C! V3 `4 C LONG m_nAsyncFindHandle;
" y! a- ]5 ^4 ^1 o9 _8 @3 S0 n" B+ U bool m_bCOM;+ _% K. t9 u7 A1 H: a+ [
bool m_bPortIsFree;! c. w z6 O. Q- F5 w
CString m_sLocalIP;
/ a! M' N E+ N! `. S' T' s CString m_sExternalIP;( t, ]2 i0 J3 Z/ y7 V3 e
bool m_bADSL; // Is the device ADSL?
; Q) w5 ~+ D* A) G$ @3 }, P bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
3 Z$ g8 e# e* f L U bool m_bInited;4 D, g1 ~9 o8 l" x) {. u
bool m_bAsyncFindRunning;2 C& J3 C' D; c
HMODULE m_hADVAPI32_DLL;6 W8 L; I0 F, O. j \
HMODULE m_hIPHLPAPI_DLL;
% r' q! Y! z( c; e& |1 P7 ` bool m_bSecondTry;# n' W4 e3 J. d: u
bool m_bServiceStartedByEmule;/ |0 Y) B$ g2 p! G- o/ ^
bool m_bDisableWANIPSetup;
1 x6 `( A% O) a9 ~9 v) P bool m_bDisableWANPPPSetup;
4 o' y/ D+ f/ x
/ V# z: k- U2 w6 i* ?8 O
G$ E' w6 h2 N4 W' L# |3 w6 Y- x};9 s# _) u# v$ S) _- q/ U# u5 Z
6 u% ]( A1 w. v& O
) m6 c; h- B2 L, c// DeviceFinder Callback! f" j' b, w+ n! _6 a$ X% W
class CDeviceFinderCallback* X2 @2 o5 F+ t$ F
: public IUPnPDeviceFinderCallback
2 A5 X8 e) m8 x1 @{, H7 a' X; C6 E& j
public:
, b2 `* t: S3 ^$ O& J CDeviceFinderCallback(CUPnPImplWinServ& instance)$ X3 U& N4 b' s! h& ^5 O
: m_instance( instance )
' p1 K Y, A t, S { m_lRefCount = 0; }
' w7 i# @& A+ A$ s* ]
" {! c. M* f2 O! D& U6 P
6 O) b9 t. g( h7 f* p9 H1 M STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);4 z& `' T) C( @2 V* X
STDMETHODIMP_(ULONG) AddRef();8 A* f! Z* o" O
STDMETHODIMP_(ULONG) Release();5 {5 r( C) \9 @0 I' S
, o- Y/ n* H$ F+ g% I% o) d( o0 O1 P; y/ |& @: V; \% _
// implementation$ h( R! X( W* ? W# K* q
private:
% j) I2 |/ h( s1 r" i: B0 H HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
" `" w! G" Q, r ~3 `6 D HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
7 p, Y8 E3 H9 K, Q. ?% z HRESULT __stdcall SearchComplete(LONG nFindData);- |7 E: Q# v# L
( n) B" N; K! C9 a. O
$ n9 X& x5 @& i" H4 z% Iprivate:$ ?0 P3 w! @& @9 R" H
CUPnPImplWinServ& m_instance;+ [; L% y4 }8 G L2 G
LONG m_lRefCount;7 {# N5 V$ z7 q z" K' T$ F( N% ^
};4 r$ Q, l. k0 {# j1 l
) R6 R2 z! ]4 D B/ ~7 }; }2 K
& x: F p. Q. |! q) H// Service Callback * h2 c$ V4 C' U- y: I
class CServiceCallback" J" H+ a' }7 H' }/ X
: public IUPnPServiceCallback
) y D) P& C ]* |& c( [; ]& `{
! d# w' t: ?) @7 A! _& l R- `public:
; i& b, Q$ x+ L' n" B+ B/ t CServiceCallback(CUPnPImplWinServ& instance)
+ \6 g& s1 `: [2 H : m_instance( instance )* ?# I8 s; y; j8 P
{ m_lRefCount = 0; }% ~: s0 D& D6 T; V# q
8 {& m+ K. ?' r5 C STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);; V6 w' H# S; {+ ]" f3 H a
STDMETHODIMP_(ULONG) AddRef();" U, G8 s* [$ b% W/ O
STDMETHODIMP_(ULONG) Release();
$ _' J3 `6 L" s; D5 Q. M& W) M5 ]1 T/ v8 o' ~4 @
6 I! K- L# x3 L6 |- Z8 ]0 ]// implementation7 I% c% j# ?, f' U) ?, O# z
private:
/ d7 [! p0 C5 Y& E HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);! A+ O& J% Q+ `9 V# H1 I
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
5 u& ~( P: U! o. ^ |+ Z! W' f
* b+ ^2 [$ j" m( Q/ r( j$ ^4 C, u+ e
private:8 |) [1 T2 c6 l9 v( Y# ?) W
CUPnPImplWinServ& m_instance;% a5 m1 l' C7 S: s* D1 _, | k
LONG m_lRefCount;
7 r2 y0 w' p& b- s2 z};
9 v- t, G% |7 V t2 k$ m( g+ P L, \) R6 \ e- R$ s
" \- L1 Q& ~0 C' ]# o+ h! H
////////////////////////////////////////////////// C( U& m7 F% x$ X& f8 z9 f
: c6 \. u, c, O2 P4 T/ t1 e& F, w% Y9 w" V- p$ |9 H* c- a! {
使用时只需要使用抽象类的接口。: v+ A/ ?* O. n V
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
! }/ g$ p. u5 m& F8 F1 d! I& ]CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
& g$ d N& b8 J: @CUPnPImpl::StopAsyncFind停止设备查找.
' W' ]* I9 X6 S* m2 u. J4 QCUPnPImpl::DeletePorts删除端口映射. |
|