|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,- Z+ W' O; G+ K: T$ L S2 K
( q! U# S9 n" o+ b. K" G9 S1 C
' M$ w* m# ]$ y" o$ J/ _% n/ v///////////////////////////////////////////
: ] ?4 T6 |7 N) L7 K8 x( [& I//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.) l8 h' P& ]$ d
$ I% w I6 H# y9 K6 m; `5 _- [" w2 v2 S) Y1 {# P7 q0 e5 R1 S0 @
#pragma once
4 S Q* ?3 V) E( Q#include <exception>
1 l$ M" u5 j! ~4 v
~0 m" ]3 A7 U# h' ]$ k6 c4 s, {# A! H7 P& _. A1 Z0 ~
enum TRISTATE{0 H- F- \4 N+ }2 I) r
TRIS_FALSE,
# d1 d }/ b" N- N2 y/ b+ K& P8 O TRIS_UNKNOWN,0 h6 _. g: C2 d/ z& Q5 Y
TRIS_TRUE
3 @2 D8 l. a, j: A2 I};
# O& L& u7 A; M9 W8 f, w' w- Y$ B4 m
, F" D- }1 e- ^! [* r6 O6 xenum UPNP_IMPLEMENTATION{
% M) T8 F* K! s1 v* I UPNP_IMPL_WINDOWSERVICE = 0,
2 A/ J- r5 h, \2 @0 K e3 P UPNP_IMPL_MINIUPNPLIB,6 ^" ]& [8 J8 e. u7 ^
UPNP_IMPL_NONE /*last*/6 @+ D" Y. }+ w; p8 C( d; K
};7 o9 C2 `! i- `
. i8 v9 I d/ u
9 q L x3 o7 Y! P3 s U+ e2 s
$ s1 X0 i# w; z( H k' B& v
7 |( y1 u. z" I& q( u+ gclass CUPnPImpl
( W: [8 H0 f. |) l, R Z{
* R& |. K% r; epublic:" u I" w3 k6 s4 Z, f v0 ~
CUPnPImpl();
0 N' g j& m+ I8 e' ` virtual ~CUPnPImpl();) d( q. _! C% {; d% e, z
struct UPnPError : std::exception {};
; u* z0 ?- @3 w6 Z: K2 n4 r enum {. t. \5 O% |+ A) f4 U
UPNP_OK,
* u' K( X s/ Y4 d& r9 ?2 K UPNP_FAILED,
+ q% B) t i! x UPNP_TIMEOUT* _9 w8 ~7 d7 B! U
};
+ a4 a) R! L1 N, I2 r$ p5 u3 t0 ~1 Y$ ?8 ]+ q5 g! p$ h; _
3 F% Y& M& q6 p, e5 [4 q7 {
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;# o8 M# {3 A9 Z1 G
virtual bool CheckAndRefresh() = 0;
8 f6 D6 |( ^/ _9 W, C virtual void StopAsyncFind() = 0;1 t$ \" ] V) r* h
virtual void DeletePorts() = 0;4 y* z9 X; U* ~
virtual bool IsReady() = 0;% Z# [( ^4 O `, y
virtual int GetImplementationID() = 0;
3 F$ G' I0 W+ L [
4 m c, z6 c( T2 y" G void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
+ o, z8 g$ N+ w: j7 H, i
% Z% b4 K- N5 q* {6 Y+ Z6 S8 ^/ E0 t/ W# _+ q! d
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
1 E0 d0 w/ y$ k TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
& g# P! E& |; ?- I$ V4 I uint16 GetUsedTCPPort() { return m_nTCPPort; }7 r7 g- i& x% u' e
uint16 GetUsedUDPPort() { return m_nUDPPort; } ( H, y! |& q0 f" K: W
0 F8 ?8 T" j3 G2 e8 J# o$ {
. A7 B8 H9 `' x' K! h# L1 F& k' S// Implementation
5 ~' {4 y8 |/ V6 M o# e4 Cprotected:" P$ T8 k) d) |
volatile TRISTATE m_bUPnPPortsForwarded;
3 l, ^( s8 K9 R6 [3 u" d. ] void SendResultMessage();
u6 v4 B9 e. g5 i9 s/ s uint16 m_nUDPPort;
: K/ Z+ |+ u2 k( c# _9 x uint16 m_nTCPPort;
' u, F+ F: K* c uint16 m_nTCPWebPort;
1 e; F& N! S2 e bool m_bCheckAndRefresh;
4 u( _; ?4 @( V
, x; \( Z2 E. j+ L: v5 T8 D1 K7 O0 N- m. d
private:" @+ ~$ J" }- g% j: x
HWND m_hResultMessageWindow;
; i8 E% ?2 n& D- ]* i$ d ?2 Z o UINT m_nResultMessageID;
6 p! v0 s# s5 Y8 @' j; H1 H1 l2 }# M9 @4 O+ K- H8 |
9 v. S4 k0 Z1 i0 j
};$ q3 I$ U" {4 S0 \9 C" b" K
* o& r' f0 e+ G; u2 m( R
o w9 t/ |, M. Z& V' h" j: B
// Dummy Implementation to be used when no other implementation is available/ J: M: |& }! V' M! \0 j
class CUPnPImplNone: public CUPnPImpl
5 k4 t# i) P+ e) r; L0 K/ G/ H{3 |7 p7 @ D$ J9 G
public:
( G1 D/ h- e% m* i virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }# x S" a5 g3 S& O2 U& g
virtual bool CheckAndRefresh() { return false; }+ l t3 c/ W' ] E2 Q$ Y8 ^& k
virtual void StopAsyncFind() { }" [6 |/ r: [+ w: u5 J" \% u* f
virtual void DeletePorts() { }$ a; V {* U7 n
virtual bool IsReady() { return false; }6 V1 r- _* f' M2 k3 `
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
' l9 j* [ X6 Z6 F}; i- P) W/ d3 F$ ~
2 ?$ N$ T7 D8 A" Z# A
R B, ?0 o- J7 q9 q) R! i3 t/ D
/////////////////////////////////////- }% p1 T$ Z' G7 a* b9 n2 b; R' V6 N
//下面是使用windows操作系统自带的UPNP功能的子类
& X% r) {$ G; Z. D' y
5 O6 ~0 S) [. ^" U4 x! K h% J( R. E8 b7 V. b$ z
#pragma once
2 V0 d* J# \2 S& v& e2 G#pragma warning( disable: 4355 )
, H# s- ]; b$ B3 R( |/ w! S
- n: O# h6 H9 y; Q3 C" B6 E. I. n! ^
#include "UPnPImpl.h"
) G8 B/ m' y: B9 h0 q! J7 r#include <upnp.h>; S( M+ B9 _8 Y: ?8 G7 H
#include <iphlpapi.h>; Y, Z2 L1 w I/ r2 K. z2 @
#include <comdef.h>- @0 K% A& r7 l# {6 V7 X
#include <winsvc.h>
Q- Y% l4 d4 k' D4 @1 g: Y* b$ E" W# j- t' x( X1 T
1 V d+ B; I) R6 f7 Y* W* c#include <vector>- h* v8 J% K: z: ] Z' ^/ O3 T
#include <exception>- P1 `1 k% ]% e
#include <functional>
( o O2 K& w# E' }
2 q; @* ^5 P+ ~6 `) q$ b
* `: |; d3 e) f5 x9 c1 J
4 \1 l& B6 u: r' G. z5 N* u
+ D. H5 o" e$ a' ^# Stypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;- c2 n. h/ `; F" y# J
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
4 x. ^/ P9 L" ~& ^0 b+ \typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
' M; ~+ ~4 ^: ptypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;" F& \6 s8 g. t9 [; m! F
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
9 f I! ` n+ `+ G' G! a4 s' ztypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
9 |& m# _1 M G8 e ttypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;# q% O* x" V8 Q8 o U! y6 N1 P
( x5 e7 P9 ~6 F7 Z3 L
& y3 [& D6 ?5 B* y5 Y9 G( ztypedef DWORD (WINAPI* TGetBestInterface) (
6 h% o* [. `4 e1 i; [7 [ IPAddr dwDestAddr,4 c+ p( H, C4 N% r
PDWORD pdwBestIfIndex
& M7 V$ l: g6 R8 F7 u);
U+ Y* z7 Y5 g6 S% X1 U! `! d, t1 F0 {3 J! T
. D% u" w% G- o Y; Ztypedef DWORD (WINAPI* TGetIpAddrTable) (0 }) \6 |# K C
PMIB_IPADDRTABLE pIpAddrTable,
* d8 r( o* l1 ]: ~. p( Y PULONG pdwSize,* Z" I* C+ w9 p$ z
BOOL bOrder U* q! w8 y! M
);
. s4 s8 W6 S8 U" S6 t) `( I6 n4 o
/ O; v% _; N+ m; jtypedef DWORD (WINAPI* TGetIfEntry) (
% j( T( F6 G' O- O# I: s% | PMIB_IFROW pIfRow
: J6 y4 c) V1 [( C. g3 y0 H* E);5 l( L0 e1 a- t1 v3 D
, l* J, x7 p. C, B, |
2 R) |1 ~ P( r) R9 X. U# ^
CString translateUPnPResult(HRESULT hr);
3 b( a7 ~+ J7 I7 \- LHRESULT UPnPMessage(HRESULT hr);
5 ]" T2 L5 f {# G1 m6 E8 s+ f$ }/ x3 T1 S; m$ t6 S/ v' m
7 H# ^: T6 x- }- c+ R
class CUPnPImplWinServ: public CUPnPImpl
4 }5 \/ S8 i# `) C$ {( L# W% f{
j, j& }+ } a. H friend class CDeviceFinderCallback; s+ b- ~# r8 ?6 s* {- ^% w
friend class CServiceCallback;
; ^- J6 H6 N# W- P- Q// Construction
" ^# n+ J9 w# E4 p' i$ I3 e/ kpublic:4 j# t" x9 d9 M% i
virtual ~CUPnPImplWinServ();5 t- |! L9 L9 p- D1 `3 G$ w* D
CUPnPImplWinServ();
3 Z3 T! B9 y) O) w2 X, V4 F2 O. G8 F
% O3 J! N4 H! e/ N$ d7 l# b8 I5 S
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
) Y% p6 E/ i& o$ u0 v4 W6 V; | u$ k virtual void StopAsyncFind();6 _$ B2 E8 b- P8 H/ V. { j
virtual void DeletePorts();% _0 v. s( P9 w) P
virtual bool IsReady();; p; A5 n3 E& J5 I) \" c n
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }; {: w! f$ }3 i
) f3 V, b* k- F/ A8 r' ]
8 [5 d/ X K- L0 K6 f" b | // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
0 I7 f, \4 e6 C6 P; h% h! [% t // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
+ y: F0 |* R% u. F! z H2 J virtual bool CheckAndRefresh() { return false; };' v0 e* d' ]- R6 _- u
& L$ D5 A4 N9 p6 T& x( F. s0 ?
$ b& B4 S+ Y6 Z) C/ N- y! o
protected:
% D8 H8 H- j9 Q2 F1 C$ v void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);+ p7 {# Y0 N- K8 O% d7 ~% e( |
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
# L7 Q8 q/ q4 ?, i) C void RemoveDevice(CComBSTR bsUDN);. A: f: U' r( w" Y4 K
bool OnSearchComplete();& y, N+ L$ D L% p' `
void Init();/ E/ s& P* \: N
2 U& b$ e# r5 Y5 `1 B9 q' ^
9 q4 k0 r7 t& r6 v0 Y inline bool IsAsyncFindRunning() 0 t* ~% B" W% H8 |
{
# U% G% D M' K/ X8 ?. z3 E) }+ k5 Q$ G if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
! u' P+ E+ }, i% P! x# v {6 F% f$ o3 J" Q$ n) m; l b
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
- C* B5 ^1 |7 u2 I m_bAsyncFindRunning = false;. O; x } a0 N
}
5 o% ~' m$ }! C/ ~2 a J" ~2 U, l MSG msg;
; p+ F* m0 U. @: [( e while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )) s9 y" f2 E' z1 ~4 f; o. R
{
. v7 T# E, {1 Q$ |8 }* e' F1 k, u TranslateMessage( &msg );- |6 `9 a7 D8 d" A
DispatchMessage( &msg );( d: L+ B5 f8 R1 b, Q2 m, t
}/ M3 j7 I, @. ]6 s
return m_bAsyncFindRunning;' S3 ?# y- i# | F2 M; |
}
) |' z' e, s: N0 L
# @7 `4 `# H& a. c5 K+ u
# _* H( e- b# i, l% z- K3 u& y/ @ TRISTATE m_bUPnPDeviceConnected;* x2 f# ^: E- g/ w
8 O0 f- D+ N6 H6 o/ q
% [3 ]' \% Z& G4 _# m// Implementation
$ O8 F- N- x5 G3 j // API functions
' m& K) W7 Q+ Z# p+ [ SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);' R, h# j# e& [ X0 {: ]* }
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);* A5 U2 J' x1 Y$ ?' R4 t5 ]
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);; u, S0 Y$ q% T) e, o
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
* {- q- s1 _9 _4 \' {0 V6 [0 t: a BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);# n# Y0 |7 f- I$ y1 j: r2 q P
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
1 c2 C& h5 {/ Z3 g8 x
/ c/ Y# a) O# P1 u; E3 r: x
- Q v2 Z4 `/ {% A) \ TGetBestInterface m_pfGetBestInterface;; S! k6 w8 P& C% ?% s! \1 l! @
TGetIpAddrTable m_pfGetIpAddrTable;" k( i! r. p; p8 k) d" n- O
TGetIfEntry m_pfGetIfEntry;$ b- }2 R) X, W6 i$ P
7 z9 } R4 l" C$ T
; n; [" L4 ~4 P3 N8 |* F8 j static FinderPointer CreateFinderInstance();
( s L3 J& n9 J: \( P9 F' P7 N struct FindDevice : std::unary_function< DevicePointer, bool >
9 G* A' P0 H; _3 } z2 k+ p {
; v8 f4 x4 I# l7 q2 e' P2 f5 l FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
4 O" }' s1 U. }# x- A result_type operator()(argument_type device) const
3 b- @$ r& U6 j' Y; G6 g/ Q {
- h( |5 c4 b8 G, { CComBSTR deviceName;
; {7 I" }5 `/ E. ? HRESULT hr = device->get_UniqueDeviceName( &deviceName );
' R0 ?; j, O! H8 ]) U& G
# L5 f! |' y+ j$ `4 _) w4 V/ X9 U; u, i+ s
if ( FAILED( hr ) )
- Q B: C- p w) J' x: w7 Q return UPnPMessage( hr ), false;
7 x& n5 _2 x) T+ B, P
% H f) E- {" V/ w7 f2 Y& f3 n! p) K. S1 W7 o" d5 P
return wcscmp( deviceName.m_str, m_udn ) == 0;
$ l8 L, W) `$ x; g }
1 b4 w" N3 E7 f6 p: v4 K CComBSTR m_udn;
7 [% v+ n) M, T3 S" I( t; k };
5 ^. t5 w1 w+ P
* S. a: t. w4 Q5 ], R* L void ProcessAsyncFind(CComBSTR bsSearchType);4 z+ w. I& X1 u5 k
HRESULT GetDeviceServices(DevicePointer pDevice);& R7 ^& m, U% _! ^( Y
void StartPortMapping();
8 f' W) H8 T; R+ ~ HRESULT MapPort(const ServicePointer& service);4 @( [) q; E, t( E) m0 \, r
void DeleteExistingPortMappings(ServicePointer pService);" N* [3 ]# @/ {$ {6 V1 V
void CreatePortMappings(ServicePointer pService); I, B! N" }6 j. |: t; e H
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
' d1 V; M8 ~) A. M3 d HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 9 N# c+ V7 Q" e
LPCTSTR pszInArgString, CString& strResult);2 B% Y- U- l. c) g) C5 U
void StopUPnPService();) i9 {0 [2 {0 M
- x8 H8 u" X1 _$ K- n! W; K' ~$ J: G& S
// Utility functions
) q$ ?" T( C: \3 e5 s5 N! U HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
. r6 N7 Q: Z2 g$ K- D' j0 }5 b INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
2 n# _/ _2 m7 a+ [) X5 h INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);7 ]9 g1 w& k8 |% K
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
/ A0 s1 ^6 `5 `8 ?. i% W$ n9 S HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
; o% I6 m. T& B3 q" j HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
( k3 _2 K* F* o( h CString GetLocalRoutableIP(ServicePointer pService);! E9 k9 ~* C8 P+ @$ x" r
* {% H$ B r2 w D6 d, U6 B( _$ J# a) A# n
// Private members
# g7 r: ?# f9 j6 _private:5 @4 `1 z* o7 l3 d, f6 h9 B+ y
DWORD m_tLastEvent; // When the last event was received?
2 [0 ^1 o* a& F w E- \. X std::vector< DevicePointer > m_pDevices;
& d5 I2 q* l# U0 c/ @: A3 o std::vector< ServicePointer > m_pServices;
5 Y j1 H. S1 p) ? \# p/ M1 a FinderPointer m_pDeviceFinder;% K8 |2 `- x+ l6 s. H5 e* ^) f
DeviceFinderCallback m_pDeviceFinderCallback;
! m6 U# V2 u0 V7 N3 k9 z ServiceCallback m_pServiceCallback;
1 ^ F7 p1 p: k3 t* R
5 Q- {. b5 s. k! }" ~! D: c! k' n _( `$ f2 R. \% b
LONG m_nAsyncFindHandle;' F7 f) g6 A/ v' Z$ T
bool m_bCOM;' |% f) n" p7 Y' ~
bool m_bPortIsFree;1 e- \' f' A4 e7 I
CString m_sLocalIP;3 E, H: u3 v: C+ A K% G1 B
CString m_sExternalIP;3 e- ?- r/ R0 O
bool m_bADSL; // Is the device ADSL?2 g0 h L! C; V$ P$ S7 t
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?/ m, |5 q; l3 J$ Q: ~3 k! o! t
bool m_bInited;
; [* _( N6 Y+ `3 m2 a bool m_bAsyncFindRunning;
8 V* K. Q% X7 U, B( ?8 W HMODULE m_hADVAPI32_DLL;. j. f# @6 \/ E! w
HMODULE m_hIPHLPAPI_DLL;
( k) P4 u0 h0 C7 r3 @ bool m_bSecondTry;
" x, I5 ]. ~9 D4 O" A! z bool m_bServiceStartedByEmule;& d$ c0 v, s! A8 ]5 H$ z
bool m_bDisableWANIPSetup;/ }' R$ A3 ?+ r3 K2 m
bool m_bDisableWANPPPSetup;
$ `- r! s1 f4 z. {/ F& b" a1 b' ~3 B7 Y( S4 C% i3 }
U/ s/ W! K1 T' n3 ~3 G& q8 O};
' d I) u! W( o% L0 t$ {3 U
; [* O# h2 v0 H, p
- g, ]0 ~7 [% t// DeviceFinder Callback. p/ ~" [/ p" i2 n! I0 k3 V! M
class CDeviceFinderCallback
% R3 h4 d2 I# }+ C, M : public IUPnPDeviceFinderCallback$ N/ _+ U/ T; r: I
{
) N L% Q5 d! Y" \( Y2 q+ Epublic:
6 @4 H8 U4 f! d/ A1 f3 d CDeviceFinderCallback(CUPnPImplWinServ& instance)
0 I; ~) P. f3 y9 M; @ : m_instance( instance )
9 p3 w E2 n8 _& ? ` { m_lRefCount = 0; }6 k# A& E; @+ s) P2 R7 o' x' B7 F
) t& j+ E0 C. ^6 p
2 A6 u% }1 b% ?! o$ O
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);; T. _' ?- _( f/ f
STDMETHODIMP_(ULONG) AddRef();
' d- G* L9 |" {& y( A STDMETHODIMP_(ULONG) Release();6 n$ C8 s2 `3 L
+ w% Q7 n4 B# Q5 u. }
9 C( j3 ^4 Q) c4 m// implementation
0 [0 T+ v8 k9 D9 g& ]private:
1 w7 X! F1 }1 L; \4 w; h HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);9 @2 m" ~8 J' [; W* |4 W
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
* O$ T! y1 T8 F# v3 F4 d" i HRESULT __stdcall SearchComplete(LONG nFindData);
7 Y* g8 Y- N! h6 ~# j& X5 \6 B% I# K; Q7 l8 g2 h2 [. h; i
' B# }" U$ a9 R) |2 r; ]* o
private:% ]% Z( z" N2 J V
CUPnPImplWinServ& m_instance;+ C0 |( L$ w: y* `2 u M6 W. a
LONG m_lRefCount;
( \: m/ ]& H2 Q3 d* I* ^};
$ u6 T) i/ h+ {' @8 d; s2 W, v5 r b2 \ }
" h$ Z/ y* e5 R& x9 a$ @2 L9 e( E
// Service Callback
1 M0 ^" `) Z0 n+ m) O7 }9 D$ iclass CServiceCallback( u- s. o0 S* G+ r3 I% W8 X
: public IUPnPServiceCallback
7 S; F3 X$ ~% p$ K- k/ X$ Y) A& S3 S{! N6 X/ G: S8 z
public:) y9 e9 \0 ]9 ^2 n) @
CServiceCallback(CUPnPImplWinServ& instance)
) G9 U" a' O) f/ ]# u : m_instance( instance )
$ Q6 I) K$ t6 m% y0 T { m_lRefCount = 0; }; ~* n b% s, {$ f0 P0 H4 y
/ ?& T$ L- W' x9 v k5 ?3 o4 n( S
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);1 s8 S0 v5 C6 d: T/ K+ L6 E
STDMETHODIMP_(ULONG) AddRef();, |! i9 j1 Z6 C& J
STDMETHODIMP_(ULONG) Release();6 x* ?- V( }# ~# _
( B$ r( i4 D* M+ s0 _
8 u' j1 m+ W* H$ o& S// implementation
5 I% f1 B: Y0 _9 T, i( o1 r3 _private:! `% c- E7 I0 g' W" [ J
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);% n) Y9 l. t+ ]- ~1 {
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
! n. u4 g% ~9 F' h- f$ ^+ F- n
2 @; F1 y9 U' q% O+ u A1 Kprivate:8 s e$ w% ]- q5 }& o& I
CUPnPImplWinServ& m_instance;' @6 j3 y- S' \2 ?2 [$ |
LONG m_lRefCount;% [/ }' Y5 [# l- \$ Y" p1 M
};4 {4 ~1 y; A8 C, e) N3 ^& H7 P
& _) i Y# ?8 |' Q! g: N- B: O
, l9 Q8 v- x/ y) g9 P
/////////////////////////////////////////////////
8 d" u$ y; v T" v# j; Z# r' ~. W. a4 K
9 r- E9 U5 i- n/ z
使用时只需要使用抽象类的接口。, Z/ O! ]9 `" Q
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
( n0 N7 [( K$ ACUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.' ?$ i$ S4 s. Q& L) I; r
CUPnPImpl::StopAsyncFind停止设备查找.
/ Y6 v- m! [/ r' PCUPnPImpl::DeletePorts删除端口映射. |
|