|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
8 [! L$ y0 L" X8 v% V3 O: T3 A; `6 q7 e8 V
2 R% O, ]' `! P///////////////////////////////////////////
+ K- K+ H/ F; z! _/ j% M7 ~//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
. g; F+ b$ R S9 ?: N. i( K) k; A6 u t2 }
+ R2 B) e( L, W
#pragma once% E4 a: E7 _1 g6 p
#include <exception>$ Q: [/ B8 S7 p1 u0 ^
d! k+ s4 H- C& n3 l1 q, t# z- }; D/ U( u- N
enum TRISTATE{
* m% M9 R( j# Z6 z TRIS_FALSE,) F5 I9 i7 r. Z3 Y, w# ]
TRIS_UNKNOWN,
3 e1 k1 g) V' g TRIS_TRUE
& \! V% M" S% n% Y- r' Q ~};) s/ @2 {( P( o
3 }1 M$ j6 K e' f( T$ E- ~; ]7 s% h% Z3 H. @- T4 a& H' n" G
enum UPNP_IMPLEMENTATION{
' z, \- u: H g3 h" q% |/ Q2 g UPNP_IMPL_WINDOWSERVICE = 0,
9 q5 s A4 C3 \2 g' G3 z" D8 B UPNP_IMPL_MINIUPNPLIB,
* [9 c6 [, C2 v UPNP_IMPL_NONE /*last*/
/ |; d. \1 B1 o! W" t' m};
* Y$ V: q. t* E3 c7 u& Z4 D: o0 ]
/ d3 X8 Q3 {' G
5 o- b7 \0 C2 _5 z
+ A2 S6 I) u- Q; y; i4 x
class CUPnPImpl3 j- ~4 @/ k0 H
{
7 L* F' T' C) I7 Y; lpublic:8 {" `9 k2 W3 f' u$ v7 ]
CUPnPImpl();: y1 j; U1 |( f) U/ x
virtual ~CUPnPImpl();
! ?2 ^3 Q6 i5 z- r) \1 _+ k% n struct UPnPError : std::exception {};0 L/ A8 G- X* i
enum {
) H% y6 j5 O' V5 @. F/ v! N UPNP_OK,
, r {- r6 B H4 r UPNP_FAILED,/ Y. j" S, S% a5 j) N" l5 B2 g
UPNP_TIMEOUT
4 a3 g c- w! | };: `8 k w; ?% i) X3 R
# u y6 D8 k/ r$ l
3 _% s0 {+ y6 I
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;" r8 w7 z$ ]5 X8 `. m. E# N
virtual bool CheckAndRefresh() = 0;
/ n+ @7 q& j$ q- y! X: l virtual void StopAsyncFind() = 0;
2 n5 f4 F4 t1 V' ~3 E virtual void DeletePorts() = 0;
% K# ^# k" s' g# D+ _, [, R1 z) V virtual bool IsReady() = 0;9 ~& q6 E3 K) _
virtual int GetImplementationID() = 0;
8 w1 Y& }4 I( @0 W6 {( h
$ B6 `9 C" [0 a ?1 A' x: b1 { void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping9 k2 ?" T" y u" k6 Z1 C3 |
- L) n- Q: b. V
^+ m8 X" Q8 }( q0 N. D: U
void SetMessageOnResult(HWND hWindow, UINT nMessageID);; s, F/ ?- v- Y7 F! A; D
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }0 z; E- f1 o# ]+ i; o1 ~
uint16 GetUsedTCPPort() { return m_nTCPPort; }0 l/ j9 m- l& a" F- J# I* y
uint16 GetUsedUDPPort() { return m_nUDPPort; }
# R. R' L( i) H6 W6 U( W; B8 f6 G% j' S" ]0 [! _0 V3 |& b2 o6 |
4 k. C3 v' D3 }$ j
// Implementation3 V( I/ P0 u3 ]. k
protected:
' a. m/ Y) f( d# i volatile TRISTATE m_bUPnPPortsForwarded;
/ Y- H7 T; _! S$ ^& [' ^& E void SendResultMessage();
& w, j$ T' S4 C+ ~# o; p1 j* ] uint16 m_nUDPPort;- W/ C# V" e. S% d) D% l
uint16 m_nTCPPort;& ^' r6 ^3 D' e8 M
uint16 m_nTCPWebPort;0 B [* G2 z, }( T
bool m_bCheckAndRefresh;7 u/ j8 F7 |: W6 X+ A# _) B
. p: S- x5 ]2 o) _
* @1 l. w: Z" C' U8 W3 z; ^5 o2 [private:
8 c5 N7 ~, T8 O HWND m_hResultMessageWindow;" J$ y2 m$ [1 g( H# y) N, s- S1 K
UINT m_nResultMessageID;
, f( v& h# X: o8 l: g
& R1 i1 i/ o5 I, R: x6 s" T/ w1 _& N: s9 I. U& v6 y+ i7 A
};9 j% E" k+ |$ b" v7 P% r
2 k/ [2 z; d7 T* _4 D% Z! t$ P) f+ S, K) \# i D3 t0 ~2 l0 }
// Dummy Implementation to be used when no other implementation is available
. X% k j7 ^4 D ^: Iclass CUPnPImplNone: public CUPnPImpl, o8 N1 ^! |9 w* k) r8 c/ E3 Y
{( J* H" n' h% p, S) f
public:3 X4 W5 h: r, C% j% @
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
7 M3 ^ P4 H Y* v3 ?" G5 z) ? virtual bool CheckAndRefresh() { return false; }5 F5 Q& a1 @6 E7 N" w* L- C
virtual void StopAsyncFind() { }, @7 B$ `% O: y9 \6 \+ H0 B
virtual void DeletePorts() { }
8 g# h' t% Q" [ V/ c: [ virtual bool IsReady() { return false; }4 ?5 p( Z8 o% p) M
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }% u! v3 `3 i+ E9 B4 X
};
1 K6 ^, K2 V% g' b5 h9 ^) m
; B7 k5 E, Z# J/ K
% q7 t& M5 R! ^6 i4 `/////////////////////////////////////
# O% O, x0 j1 z; Q7 A! s3 v9 o//下面是使用windows操作系统自带的UPNP功能的子类
6 G; a- Y, A/ }+ o. A* D' ^6 @/ Z+ V6 A( @& E
* c- ^) I" G, A- `/ D#pragma once
8 q( |! N6 l, V- h" x" Q+ F8 M6 n#pragma warning( disable: 4355 )# P& p8 [: Y0 l$ x; n; C
, a& {: x) V1 ]% N! `( O
}& o6 C# k' m0 {! B- r0 E% r! J#include "UPnPImpl.h"( z( j% L& Y# {* {: }
#include <upnp.h>4 h- W7 W8 T0 z; U1 I7 o3 z U
#include <iphlpapi.h>9 u% }; x% Z- |' o* |" [# |
#include <comdef.h>/ J/ k( s, p a, i
#include <winsvc.h>
6 v/ ? A$ W( I- @9 @8 x' z( O) d
2 ~# ~5 p' {& V: r }% L* `6 z. u0 B6 I) i$ }
#include <vector>
2 w7 c# J; v3 Y#include <exception>
- p c( P% n- n) D#include <functional>
2 B% p* d7 C9 H/ o4 ]
, d" l( B( g0 l. f2 ^
) Z4 D: t% \0 t$ f( i/ f, b ?7 k9 y" ]( t+ N# k# {% ]
}5 s4 `& Z' Q) Q$ v8 M, s0 t$ `7 s
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;, A& C% g! b* ? o
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;, B6 V. t" r! `* S6 Q& {
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;+ ~2 M1 O( w% `) D/ X
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;- Y9 @0 y' U& |5 k
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
3 u# ^+ q, j$ M! M. Wtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
' U+ X7 K1 T1 [9 g: V( |typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;0 Q) o; i4 t9 D+ j9 q; K9 P% [( Z
" D( B+ z5 Z4 u. Z; ^2 v
. J4 n* [; R; r0 F) ftypedef DWORD (WINAPI* TGetBestInterface) (
. T( g0 }% `3 [ i: P IPAddr dwDestAddr,
" Y: e4 h; t9 [# S3 N" w PDWORD pdwBestIfIndex( F4 V7 y( i( g
);
) w/ A3 u+ C* R! L# h/ `5 E" H0 ~' j+ T: M9 |+ e
" j9 s# a F) Ftypedef DWORD (WINAPI* TGetIpAddrTable) (
5 {' ^4 ?0 ]0 N PMIB_IPADDRTABLE pIpAddrTable,/ V4 y" G" c* B
PULONG pdwSize,
/ K0 x8 E7 c! i1 z4 ^$ o" z3 U3 r BOOL bOrder* z! [' S' M' `
);) F8 R% W( [$ s4 f; G7 `
/ J9 C* b( T. t( m( U4 q7 R
! Q% B F+ K- |typedef DWORD (WINAPI* TGetIfEntry) () I' P# `+ m% a# f; r
PMIB_IFROW pIfRow& l& ]' s* f; d" k5 h' W
);
; L, C) v: V- K$ H$ w6 x& a4 A: t% c5 ~7 _
4 s: j7 L |/ ?$ c, `
CString translateUPnPResult(HRESULT hr);
/ n/ Y& P2 M3 ?HRESULT UPnPMessage(HRESULT hr);
+ U5 B$ b% q! L, T, P7 t8 |! v- I c0 x
) J) }8 x: c5 Vclass CUPnPImplWinServ: public CUPnPImpl
9 X4 ~9 u4 ^; m* C) z{
$ _. _) n2 a' I, P4 R friend class CDeviceFinderCallback;
" @& `3 U6 P5 b1 V$ `+ E4 r friend class CServiceCallback;
9 D: O) V7 b t: Z# W* ?4 F% G# N// Construction- z2 l* m g; U2 c6 r
public:$ r: @) o) Q$ A2 m7 O7 y' N: ~8 o& X
virtual ~CUPnPImplWinServ();
m8 h. ]; Y Y' d8 t( r" `5 R CUPnPImplWinServ();
0 h" W5 x1 k% y, y5 s7 d
1 Q- u/ c; v2 ^; }& G( G, P2 N/ Y4 P8 b3 ?! O1 i( I# _
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
+ ]# O9 ~9 j8 f L5 I; h7 }: S virtual void StopAsyncFind();# R. O9 P, f; w+ f9 B) R
virtual void DeletePorts();
! E; h4 `+ G+ X* i virtual bool IsReady();# F) t% M: u1 u% m. C8 t, x
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
8 v* h! i* e; E7 ?0 {* m" m) M/ ~
) ^6 v- }& a7 J8 X# h' `9 [/ f% B& E( h
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
9 P. O3 L+ w+ {/ r& ^ // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
/ U, k) [6 d/ s( v* y0 L6 B virtual bool CheckAndRefresh() { return false; };; P9 R7 F" U: [0 A
' c3 F1 J0 [( g: A! R( M
' V1 [* m+ v$ K' A9 m: |protected:
. i' { B) V0 ?$ T; }$ N void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
: C" E( f/ ^6 @& {! Y" K void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
8 T# V/ N9 |% L; A, T6 [ void RemoveDevice(CComBSTR bsUDN);
0 e5 t. U6 Y- ^ bool OnSearchComplete();
0 ~% z2 n4 t5 c6 E% {$ ]; o. H, V void Init();, r( T) d8 y0 n3 F% t3 x' u. h' G
: [# v# r8 k; ~. K" t. m3 I. K3 G+ f" {5 q5 }) H
inline bool IsAsyncFindRunning() % W9 k5 `4 v, |* W' Q3 s3 B1 K
{7 Y1 _- g9 ?; K2 b
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
6 T* o8 A$ E# e# n; ?- _ {
( c' ]& H9 M' d9 Z) v9 ~ m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
& Y' g5 o. M0 I5 n m_bAsyncFindRunning = false;& b9 J4 C3 [7 G3 X; ^- p( j5 i
}
5 i) E9 L0 |, f( m4 s MSG msg;
+ Q: M- j( k1 Y0 _: r while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )( Q: x [8 D- h1 k- }0 J i
{
3 }. z& N" V$ ^0 o' o TranslateMessage( &msg );0 e7 _+ h0 A9 ~7 N* \
DispatchMessage( &msg );
' w+ ^/ u& z" h6 g }& |; v8 h% d) v+ ?! k
return m_bAsyncFindRunning;
. X) Y1 D! k- x: Z, m6 J/ ]7 O }
! m/ r# w9 ^6 b, h% e) u9 p$ j* e: `% s4 A7 x* p( `; u$ z$ l
% ~$ X. v% d* X {0 T' ` D( W TRISTATE m_bUPnPDeviceConnected;
% Q0 W2 _+ G. ?4 |1 c4 j1 {3 ]9 v- A: r Y1 d
7 q: k2 q m% k1 h4 r// Implementation
2 `5 g: J( G+ {$ N4 a* M* ]. K // API functions" N" P1 o5 Y- q; N& \# X- C; Z- \
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
2 M1 C, e% U! A) h& ~, q5 c" ^ SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
R; M6 f; t$ k4 U% c9 { BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
& i& h) o+ |, N4 e( u! P8 l W BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
- L. _2 w5 t: p) d BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*); O% A+ C6 C: E3 }3 l& X1 v7 S
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);1 o8 N2 a/ y! e F w& |- O$ q
# e ]) a8 c$ a1 ^6 ?9 `: G
& d3 r" ]/ D* S' O7 F4 o TGetBestInterface m_pfGetBestInterface;
5 x; J) O4 p; S TGetIpAddrTable m_pfGetIpAddrTable;5 t' Y4 o/ M- ~8 k0 ^* Y" j( _
TGetIfEntry m_pfGetIfEntry;% }* E: }, `8 o) ]. G
; i- x9 Y( T* w8 X9 q _8 M6 h, p+ V- w) G
static FinderPointer CreateFinderInstance();
e' G1 D V* M8 t; u9 e6 U1 Z struct FindDevice : std::unary_function< DevicePointer, bool >
/ E( f9 V, L$ `9 O+ H: B( k. z {
* q/ B5 A& N9 ^/ L FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
8 `1 L8 H u: z" o3 ?1 h/ } result_type operator()(argument_type device) const' z$ ~0 W/ r& H; i- j+ b/ D
{
5 _: b& |9 ]! S: C0 A, V& x7 y CComBSTR deviceName;' I- \9 k& d% [6 w
HRESULT hr = device->get_UniqueDeviceName( &deviceName );. d: S( Z! H2 u, X/ q4 L, Y2 `
8 f$ ?% F. r3 u4 F" J; C3 J( H; y
/ y" E8 q8 U! ^* ~ if ( FAILED( hr ) )# x9 o# j6 n9 Q/ z$ M
return UPnPMessage( hr ), false;
: V" C+ `0 c! ?( r
& h' c3 q) {, w1 t% Q
4 _+ R$ `% {* k return wcscmp( deviceName.m_str, m_udn ) == 0;
7 l% M' }2 c' i" z: S: S/ t }: g) ?6 }- |' z1 R& x$ R
CComBSTR m_udn;1 c! s" Z4 u- E0 u6 F
}; z- j( r' W* g' {) _; C
! C$ U+ f9 L9 P5 C2 D, J( x- n) g
void ProcessAsyncFind(CComBSTR bsSearchType);. \2 s1 x$ n x8 o6 }! X# U
HRESULT GetDeviceServices(DevicePointer pDevice);
0 L. F. X6 B8 m" i void StartPortMapping();
+ V; s) K& X" |- L( \' J4 \$ E HRESULT MapPort(const ServicePointer& service);3 f( I9 D$ g- J* {
void DeleteExistingPortMappings(ServicePointer pService);
0 e2 o' F/ f) ~, ?1 W8 Y: v7 Z void CreatePortMappings(ServicePointer pService);
+ `! J5 \; Z- D5 b5 U HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);, q6 Z3 ` G: T$ ]
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, # c/ ?1 k5 t, @+ p$ ^
LPCTSTR pszInArgString, CString& strResult);
. L8 `: b X0 \+ _$ Z5 C void StopUPnPService();
" Z- \, ]# Z; o- p F
& M( D5 f `4 g& ?) s m! K. y/ C5 d, L3 }
// Utility functions
) D" n. V9 L8 { HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
& d5 f \0 p( u INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);) w* u- V$ J+ _0 O; M+ j
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);& Z0 i0 w& Q" c5 T0 f
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);4 { A4 B" Z9 ^ D- L
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);1 i% B/ ?/ a$ v8 D" c5 r* ~
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);' v4 j- ^5 @* L# O! D- Q* s2 Z; y. [7 M1 F4 _
CString GetLocalRoutableIP(ServicePointer pService);& M- u7 [; x V! Y! M, y/ v; H
; S8 z( D" R1 @; B
' K, f: T2 t y! R. A: n+ m// Private members: F# \. t: a* K* V" z/ G0 F
private:
9 r+ H/ r3 `, J- g DWORD m_tLastEvent; // When the last event was received?, X- X ]# U, ~" L
std::vector< DevicePointer > m_pDevices;
4 N! d6 A* S* y+ ]6 n std::vector< ServicePointer > m_pServices;( W1 C1 ] r4 P* n. V" v
FinderPointer m_pDeviceFinder;4 ]; s% V/ m$ P( K" I0 e* i
DeviceFinderCallback m_pDeviceFinderCallback;& [6 ?9 B ^1 Q& s! H& `- T
ServiceCallback m_pServiceCallback;
6 f- G$ x& \7 }; O' h7 ~
1 N3 g- B( h- C
* v# Y4 L/ ?* s) g/ ` LONG m_nAsyncFindHandle;
' ~- c$ y& c R( ?: E* b9 V bool m_bCOM;8 C0 g$ g6 J1 u
bool m_bPortIsFree;
1 h h7 D. n6 n8 a( O o CString m_sLocalIP;- z1 f- _* u! U
CString m_sExternalIP;
/ B7 }$ _& e! | bool m_bADSL; // Is the device ADSL?
1 S( n, Z) s, W6 ^, v1 u. [ bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
6 V' I1 S$ S3 F$ C: R/ F4 c+ @ bool m_bInited;& C3 C/ ]3 N g" G. v
bool m_bAsyncFindRunning;
0 d; L( `( S) }( i& D HMODULE m_hADVAPI32_DLL;
8 U! e, }9 Q! j9 b V HMODULE m_hIPHLPAPI_DLL;' m9 X! ^6 e5 Q( T
bool m_bSecondTry;1 @3 r" Y4 ] J% U7 M
bool m_bServiceStartedByEmule;, u7 r- V3 S1 P7 I% R; o0 c, q5 _& G
bool m_bDisableWANIPSetup;% {0 Q/ ?8 [, y: ?6 x
bool m_bDisableWANPPPSetup;
' |" F5 _3 g W' ]% o0 P
. \, v% A4 T Y$ r' e4 b# M2 e9 G1 B( e8 J0 b: a) _3 K* D, k
};
, n! {$ u3 k" M+ ^5 s' B# d- V
# n3 b4 Y8 }3 y" E* u& c) Y* k; I* n
Z, x9 x+ C5 y/ h// DeviceFinder Callback
K' [# d' A) a) q' w( e7 fclass CDeviceFinderCallback
2 Y8 U" n6 l8 w9 f/ X : public IUPnPDeviceFinderCallback
. C. h1 N+ @& x2 y* }{
; t7 S: Y$ q; _9 X g" K, D: Ypublic:. m4 J8 A7 O# t
CDeviceFinderCallback(CUPnPImplWinServ& instance), ^3 p; e1 A0 V; l
: m_instance( instance )+ z1 a% Q2 [* w( Z1 ^
{ m_lRefCount = 0; }. C8 {1 P7 O; I* j% m4 d9 C
w8 B, }. f' t$ m: s
4 X& Q- E& o6 H' ^/ W! J STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
; c: W( v7 ~2 Y8 L4 S STDMETHODIMP_(ULONG) AddRef();! w5 G$ C8 a+ x, m
STDMETHODIMP_(ULONG) Release();
+ i, R4 L ^+ K C/ I/ \
3 E/ @, m) T3 w$ W
/ z! W6 ^' _& c) j; R) a// implementation
- n( F6 V' g5 O1 E" d, V8 X" Jprivate:9 A& Q4 D9 ]7 C
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);4 Y; M' a4 a+ @& \6 H* O% p
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
+ x# L0 Y- c, C$ r- N+ k' T HRESULT __stdcall SearchComplete(LONG nFindData);
& F. a5 U m7 n8 E! @! H/ t, b% P6 s7 |, Z# l! Y
; U( X% @% i5 b* h1 U2 n
private:
. b1 u- n6 Z2 i CUPnPImplWinServ& m_instance;
" R# L. R. p: z$ d5 W LONG m_lRefCount;) s8 r& O0 n- J8 J6 t
};
) }" Q/ F6 k" o C, c1 p6 t% M) r3 n+ R% h
0 y4 U$ Z w! ^
// Service Callback
9 W/ \, T# F2 dclass CServiceCallback& j. A0 C1 |4 I2 X" [- Z
: public IUPnPServiceCallback
& x5 ^ k4 Q+ Z) d8 ]5 @{$ V- h: q0 K6 Z. C# w& N: S2 {' f
public:) ~/ s/ d* E( a1 J! j
CServiceCallback(CUPnPImplWinServ& instance)
! w( `/ s, p( T2 i6 D) A : m_instance( instance )3 }$ `4 Y1 z: n( W! ^
{ m_lRefCount = 0; }
1 u8 C6 ~4 T6 J8 I8 C+ W" e : G4 @& e0 Q6 k' c
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);/ h/ f7 K" l+ l( U
STDMETHODIMP_(ULONG) AddRef();
3 ^, v/ i$ S* a' |: m4 | STDMETHODIMP_(ULONG) Release();
' t* I" k7 `8 k% N7 d# e" X
* x1 {# M3 S2 T4 j
& N6 Z ^+ o0 @// implementation; I, V5 C5 C8 C4 }* k5 i# d
private:% A% L. r6 K; t% x9 l
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);6 h& o% S% f* [1 F/ b+ e0 V v
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
7 U5 J; ^- x4 z$ z9 P: |# y: X1 y" S, s! Y8 C V0 b
; X( N: T/ L; X( D
private:0 b. H/ ~9 K6 b; V
CUPnPImplWinServ& m_instance;% i; |4 E! Y$ J8 d4 t! Z% z
LONG m_lRefCount;
$ T" n- n+ ^) T: r};
$ d! W) _* t' B7 p
+ d! a D" p) t$ x4 K8 }# C1 @8 z3 L! Q* |% C* p
/////////////////////////////////////////////////+ i0 W* `" u& E1 ~- p4 c- ~$ h8 Q
$ M! R' I0 l8 @ a$ u' y+ I0 D( x4 p
+ r6 a2 u! z9 \2 g
使用时只需要使用抽象类的接口。+ U) \" Z$ P M* B! a
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.3 Q2 s' f t6 A4 i7 k! _7 N& Z9 t
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.; b% \ C, u7 V# e% E
CUPnPImpl::StopAsyncFind停止设备查找.
/ F9 h. s4 q3 K/ ?CUPnPImpl::DeletePorts删除端口映射. |
|