|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,9 z; k( j- R% e5 h3 Y3 t% L
' r' `1 e: S; q4 N! d
! G* @2 a/ r: g8 @4 M: w u
///////////////////////////////////////////
, }3 X5 O% k- E; P9 \8 I0 c: ^8 |$ n# Q//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
/ u- e# d3 h: o' c8 F
$ K+ y# H% Q! E; m# B9 r Z, Q9 d( K( d1 d
#pragma once. c0 s* W. p) C" A$ p$ C
#include <exception>
* d4 W& H8 A% M9 b, G l; C) a m
) n! ?3 o5 v+ k$ J& o3 I0 {0 C
# t, b, k3 T9 s5 G' Y; o enum TRISTATE{
3 W: e3 U% @( L TRIS_FALSE,
4 }9 \# ?6 u( W' O, \ TRIS_UNKNOWN,
# P j& V5 ]8 }+ H( b2 D6 Z TRIS_TRUE
5 Z5 g6 [; K6 {1 N- K};
& e3 d) r4 N2 J
# M m' }1 k; S3 [# H- c* b' M4 n
enum UPNP_IMPLEMENTATION{
0 d0 O% c0 s( k+ V" |+ D1 S$ O8 q2 Z UPNP_IMPL_WINDOWSERVICE = 0,
9 c* m7 g k5 x3 b& \% Q UPNP_IMPL_MINIUPNPLIB,
( V" M7 v0 z, G6 N UPNP_IMPL_NONE /*last*/
+ ^* o5 E Y! Y" A3 s4 I; n P" u};
0 V" v% o; q @$ H! I/ X: B6 r& [5 C2 V+ R8 f" S& p
! L3 Y" K% h8 i) _! e9 p' J" w4 z5 n# R) u: U3 R- w2 v% X* v$ L- g
+ G7 z! t& L7 J2 Z# h% Xclass CUPnPImpl
; ^! h0 _$ z+ o& r& r6 k& o{/ f* [# {+ Z! C8 n# W* Q; o& L
public:% q, Y8 O2 Y$ }) G" @8 F* f: c( |
CUPnPImpl();
. N" u* D# P% C9 Z S* t virtual ~CUPnPImpl();
1 K5 {, h- K- h4 X/ |7 m struct UPnPError : std::exception {};: G/ J7 Q$ ^5 \. ~; a F
enum {
3 j+ l. S# A# i UPNP_OK,/ P$ c+ L$ F' Y6 R4 C+ C4 X
UPNP_FAILED,% A- b9 v) o8 l( k; `
UPNP_TIMEOUT
5 V. Y4 k/ ^6 w: y+ G };
7 N0 t% M2 Q. f+ E$ O+ e3 e) U
" i, X/ h+ s6 T* X0 U( w
) ?3 B( D$ @4 g* R$ I/ c% o/ t virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
9 z0 o# P# F6 T. I6 { virtual bool CheckAndRefresh() = 0;
" Q! u$ c. V( E3 O- k1 c virtual void StopAsyncFind() = 0;
: ~% M; l, k1 N9 N( b virtual void DeletePorts() = 0;
4 F. H, h: a ]4 K- S% |3 O virtual bool IsReady() = 0;
5 g1 P& B. C* ? virtual int GetImplementationID() = 0;) ?& b' J3 m& f4 f$ Y
' r1 ^. `( c B) f+ S& u void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
8 v3 G! R: ]9 F6 o, P) u+ ~6 \) C( [$ p5 Q
/ L7 n5 ^' N) S3 [ void SetMessageOnResult(HWND hWindow, UINT nMessageID);- F* e! i% L3 {
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }8 q- H; y, I9 u0 P" F1 r
uint16 GetUsedTCPPort() { return m_nTCPPort; }
- I2 R& L0 G2 q8 k+ @ uint16 GetUsedUDPPort() { return m_nUDPPort; } * N3 [! Q. O d p/ Z
7 G5 W" I+ O, `
. w# R4 w6 ~" j5 n6 ^0 j: M. V// Implementation
7 D5 \& N' Y4 E Aprotected:* a% J |5 e. t; F- q9 O. d
volatile TRISTATE m_bUPnPPortsForwarded;
# J" E( I) P/ Y; k; S void SendResultMessage();) S& `. k% O4 _
uint16 m_nUDPPort;
s% l7 M8 K, [5 l uint16 m_nTCPPort;
4 m! y$ ?0 Z5 v4 |/ B uint16 m_nTCPWebPort;) n/ r! H- n4 Y, s6 }
bool m_bCheckAndRefresh;2 i* v7 L+ F0 k! D# e }/ `
0 \' F# B5 o6 u+ _8 w/ j A
' T$ J! I3 ^2 W! a3 qprivate:
1 v1 |4 i0 p; b% O/ h HWND m_hResultMessageWindow;% N* x$ `( ^& y. A
UINT m_nResultMessageID;6 b; p: s O v; y( T
; z) }- }* Z6 m4 _6 R3 T1 c, H& ]1 w5 n% j; k* ~) e& t
};+ L( p! y7 w# G( S5 B: Z2 `, `
+ O, b9 Z4 ^' p: L- ]" S
' t! R% X9 R" W8 ~7 L
// Dummy Implementation to be used when no other implementation is available
& ]! s- f7 ]; h% B$ a1 Yclass CUPnPImplNone: public CUPnPImpl
. m! F5 Y! D; \# D E- @{8 l' x E7 H/ u, S8 r+ f
public:( Q' L* N4 ^0 S5 I
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
/ a: d7 S+ z" d: A. L2 s1 e virtual bool CheckAndRefresh() { return false; }
9 O) F H2 l* t- L+ x: {5 i; T virtual void StopAsyncFind() { }% I; b5 o6 m4 x
virtual void DeletePorts() { }
9 s' y+ b5 \- G8 a5 D0 ~8 N% C virtual bool IsReady() { return false; }
6 s9 ~' I: P( @* X, l! d" I3 ^ y5 S virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
0 U$ P. L" p6 P! ?/ s};/ ]# W0 Y! p2 ~8 t! l! N
/ D! ]4 e) O7 Y
7 T+ g* R- [7 L9 ?+ \/////////////////////////////////////
- V7 ?' g* N% \( Z+ K//下面是使用windows操作系统自带的UPNP功能的子类5 n5 u- U4 A# x; `% j5 d
5 R6 Q- `! m0 a$ q! e2 O
0 d9 ^6 E ~; k& ~' G6 z#pragma once
. Q6 Q7 G9 t( B#pragma warning( disable: 4355 )* f8 v9 L2 ?. w6 b4 r$ e" X6 s% Z3 B0 ?
& h: v7 m2 j3 Z& J/ b2 }1 R, J
: R7 W2 d- y/ i e#include "UPnPImpl.h"& H0 v3 s, t, {# i
#include <upnp.h>3 J+ F" h& t8 c+ i# }
#include <iphlpapi.h>
( n( q+ w& x, z#include <comdef.h>
( R3 H) B, M) N0 s; ?- s#include <winsvc.h> n0 e' g) ~' z/ s7 J3 A' m+ b
m% K- I8 z# o8 r' k' r6 _1 Z
/ a3 ]! Y% R) _" w" F#include <vector>
9 ^1 H4 z1 [% {* a* R3 E0 E#include <exception>, _( Z6 e) y( {; I7 f# X4 ?' ]- \9 }
#include <functional>
: ^. h+ V+ F& `+ ~- [) f
7 B* T+ E r0 b3 B: a
5 S3 u, N1 s% f0 _ |8 s3 l9 C3 G( H& b
5 d1 q7 t7 V# j. g3 d2 @typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
$ l# |0 z/ K" z5 s" h C( }typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
) t8 n! J1 }4 Rtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
& e$ u$ z& J8 `" t. P) mtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;; K$ a: h4 e1 x8 \: L
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;' U! a/ B" @0 \' ^2 c3 v& b" P" x
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;# Q/ V9 x2 W2 `% ^
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;8 d Q# i. k9 r3 H$ E" m2 w
- K) E$ k( n# _: L' l0 y- M; U
( [! n$ B4 _# ]% Y; l2 n3 Utypedef DWORD (WINAPI* TGetBestInterface) (: b6 @6 D4 |+ F, ]# P
IPAddr dwDestAddr,* s, y1 u: S9 g, h
PDWORD pdwBestIfIndex
1 ~ d; b4 B+ \9 g$ l1 t' `);
% @, L) I5 E, t
5 g' G( Z* m1 R. Y, z& ]" V: ]$ n0 c! m* Q9 I0 x* j
typedef DWORD (WINAPI* TGetIpAddrTable) (
+ ~+ O7 H! j5 O' h! s PMIB_IPADDRTABLE pIpAddrTable,
$ f: K$ B1 S3 H! v1 L- b) a PULONG pdwSize,
" [; c0 g5 s8 X% i; ^ BOOL bOrder. i9 n5 |% R8 L; q ~' h
);
$ b+ C* o; v2 X* H! V1 F$ }
; w% B, v. X3 y4 ~ b' }
6 U+ v/ v0 D* Y* b. c. K- Ztypedef DWORD (WINAPI* TGetIfEntry) (
/ d. s W- z2 Y# ?' K$ v3 j8 c PMIB_IFROW pIfRow
, z% Q% _3 T. C5 m8 c);
( n1 P, U+ Y5 s, \' x2 ~6 x; m! W, m9 X, Q
w! E/ I8 w N% M0 j# WCString translateUPnPResult(HRESULT hr);
4 L! y z, O6 F( e* a2 sHRESULT UPnPMessage(HRESULT hr);6 S; ~# q. w9 d- |3 V( P1 L
2 ?& d7 @2 H: d8 o4 {2 J h
# F# ~- `& F3 V8 k: ]class CUPnPImplWinServ: public CUPnPImpl1 k3 G. c8 }& I
{
% Z! k' \ }' |5 O friend class CDeviceFinderCallback;1 E. U( B* t. f
friend class CServiceCallback;
% ~& A% r" m5 H// Construction
4 a0 R, n$ Z6 l7 K: Dpublic:
|$ Z) D$ F/ ~6 F% p* s' O$ P virtual ~CUPnPImplWinServ();
$ F/ Z+ ]* W8 i) |' y' |4 D5 h CUPnPImplWinServ();# e) G. R; P+ P! k+ Y. x
% d1 t( Y3 I; n# T* w0 i- |$ C+ F. w X
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
( J1 i. Z9 ~- F9 y) X% U3 q virtual void StopAsyncFind();
& ?8 q3 B) d8 l virtual void DeletePorts();
# p% Z% @" C8 s& W" f0 r$ e virtual bool IsReady();
) B7 Z8 u& M, I. V virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
4 b2 G6 [% k$ a. A5 Y! a/ Q
9 |1 `& P) Y& W) g
' F' u8 ~/ y: x4 T0 C- } // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)8 g, f S' H T Y
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later3 U1 D. y8 m( W; D% X, N3 [
virtual bool CheckAndRefresh() { return false; };
$ C# l% s% J8 L: E6 N
# D( l0 g5 L$ Y' c( C( u& M& R: |* M0 }, N0 x
protected:
" j" [0 G# ~) v1 v% X void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
' x- i* r k) F) x8 ] void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);" h1 g6 V* `$ b' f8 C0 v
void RemoveDevice(CComBSTR bsUDN);
9 n- O8 q& Y1 P1 I bool OnSearchComplete();
y) u8 Y1 h( o5 B void Init();
+ n0 ^, r I( h$ o1 A1 T9 `: e
) W0 Z# R, n4 N6 b5 T' s9 f
3 Q! Z" ~& G, \$ B* Z% ]2 a inline bool IsAsyncFindRunning()
n( d# r; u0 f q$ P: x- L {
3 g% Y7 x& a( T. t if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )# O$ R' h! z& t' a' ~( V: n- ~. w
{8 M) [! ] z2 Z
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );% c3 M- E! |6 S& g
m_bAsyncFindRunning = false;
3 t. r3 b- l9 H, u5 b }% m0 }2 X4 l0 o* Y: T. p, r: O
MSG msg;
4 G4 E5 X" j$ ~8 o while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
. b) w. Y+ B# f4 E0 x6 t1 {4 E {; Q; k) w- m5 a
TranslateMessage( &msg );
$ t4 x5 ?( H& H) ?" V# z DispatchMessage( &msg );
- O$ l4 r7 P: k! X6 ?' S }: D2 @7 @- j1 d! R; S- C6 C$ R
return m_bAsyncFindRunning;
* z+ C# N* p0 o6 g8 w R1 L1 T& j" e }+ I- X* g9 o* N2 c" y, F/ W
0 X h% U8 g3 E& x% N9 K8 ~
! Z6 Q( d {' V/ f3 K TRISTATE m_bUPnPDeviceConnected;( {7 |9 `' n( p& Y
' s% X1 Z9 B3 j( u0 {) `
2 s; }/ t% b$ w9 K1 C& s: R9 q% l
// Implementation
6 X1 ~# f9 E3 w% c' h9 I$ N // API functions
' V! w9 i' f9 c3 k& F4 @9 d SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);& Z* f7 g) g! x) n( Z6 e- p+ u! G6 \
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
$ S3 y" v4 @9 S. r9 m BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
& J& n% O$ o# M$ ]: q BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
' R7 X! J" H4 W% b/ G( ^ N& d; S BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);& O! ~1 ?2 N. @/ A$ g+ Q% N
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
6 M, c$ d: z; `* {) ]
. ~: h- U+ e- v! A- J' v8 G# T4 W7 f6 D' P2 y9 y
TGetBestInterface m_pfGetBestInterface;
_4 i$ x! D& N0 u, z9 B TGetIpAddrTable m_pfGetIpAddrTable;: k( D! k f# m1 @4 F! {5 _
TGetIfEntry m_pfGetIfEntry;
6 B4 Z, z# c6 t
5 K) C' A% Z; `3 G) @ ]/ _0 z& }8 f. j: w7 x
static FinderPointer CreateFinderInstance();3 p! D* F* G( o4 c3 M
struct FindDevice : std::unary_function< DevicePointer, bool >
- z, o( H# Y+ f3 A5 N* v {3 |7 M: n5 A* U& ^ _: X5 T1 z
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}, g4 h0 U2 s3 t0 I. }
result_type operator()(argument_type device) const
' n. F, b5 l- I& v2 m {8 K+ ~, u) M9 Z8 z t' z
CComBSTR deviceName;
+ B" V p2 v- C/ i1 h HRESULT hr = device->get_UniqueDeviceName( &deviceName );
6 ]* B7 X7 \2 O* Z- x. R- _
" f1 l5 Y$ H( R7 d
! t6 [( S: q- J if ( FAILED( hr ) ); T3 \. o- k, _
return UPnPMessage( hr ), false;
2 U! z( V3 a7 n1 u' P
& E$ @6 R' D d/ n
9 S3 v6 ?- d4 ~/ V. y. r3 \ return wcscmp( deviceName.m_str, m_udn ) == 0;
$ [- k1 R9 S( z* ~ }7 F6 N. h- h* W
CComBSTR m_udn;# |; y' ^* t5 \$ z' S
};7 v2 b$ k% N% Q
" Q" a% A7 J$ r' _* [ void ProcessAsyncFind(CComBSTR bsSearchType);0 Z/ C% R: [) T
HRESULT GetDeviceServices(DevicePointer pDevice);/ O9 n. O+ ?3 w! p8 k( J
void StartPortMapping();( ]3 A4 _1 }7 s
HRESULT MapPort(const ServicePointer& service);- r& g6 W e- y
void DeleteExistingPortMappings(ServicePointer pService);
7 S8 n7 L. p$ v! h: u" P void CreatePortMappings(ServicePointer pService);# d6 m4 u5 l X5 U/ |
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
5 ]& Y7 o* m, z( C3 N7 R+ k. y& N HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
7 E6 R, E2 L/ W" E& Q LPCTSTR pszInArgString, CString& strResult);
1 ~+ a! [( p9 c7 R* @- F4 N void StopUPnPService();' ?1 E$ f `0 m v
a' s) |' I$ g3 i
. f) t" X7 d5 _4 |+ d4 h0 x // Utility functions3 y, l+ B; e0 t! I! a
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
n. L9 T: a: t w; V( |, ^# S INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);: N7 b1 [$ `* ~6 y4 j" V2 [
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);. c+ g% l1 R! C- k
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
) j# s! I* A8 W- M0 F5 ` HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
$ I4 K8 z3 t! L2 N, B HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
- q6 J7 z/ U, e( N- R2 x7 l( K CString GetLocalRoutableIP(ServicePointer pService);
% v J" K6 V. {) }+ h
8 I8 `( j" H" r- n k" i0 e1 I
" a! s2 u8 ^( l" W5 c0 m// Private members
' q B; X7 v& m$ c; aprivate:
! m& t, m+ j' Z1 c5 A# z& |8 t DWORD m_tLastEvent; // When the last event was received?) g. S" M2 d# O" z% q; S
std::vector< DevicePointer > m_pDevices;
; `6 ?3 f; v' u6 F7 G std::vector< ServicePointer > m_pServices;6 g* ^' i/ a$ c: n# S0 }* t$ r2 U
FinderPointer m_pDeviceFinder;9 Q8 [( b8 M' f2 w
DeviceFinderCallback m_pDeviceFinderCallback;9 k% {4 f! P& x
ServiceCallback m_pServiceCallback;
- I2 V: |5 k( ]3 f# G" @# l0 _3 C+ w: a. X3 A# C7 t
5 K( M; V1 n" k/ m( q" t% ] LONG m_nAsyncFindHandle;% V$ P4 z0 y1 y6 P# L
bool m_bCOM; ~' l8 q( G0 p/ c
bool m_bPortIsFree;$ S, [! V; \4 E% J; g
CString m_sLocalIP;
2 H+ z7 S7 E" u% E: I5 K$ R0 N CString m_sExternalIP;4 R$ l9 r' g1 ^ ^
bool m_bADSL; // Is the device ADSL?
1 u- Z& j/ b0 E# L( e bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
0 T- @' s* c! M/ l bool m_bInited;: X" R( h; h4 _; S$ A5 A
bool m_bAsyncFindRunning;
4 t8 @% O; B3 e. P HMODULE m_hADVAPI32_DLL;% m, d9 a8 T) o& W$ k0 D2 L
HMODULE m_hIPHLPAPI_DLL;
" }) w9 G8 }0 l bool m_bSecondTry; Y$ P/ L0 g3 Z4 E8 g, H
bool m_bServiceStartedByEmule;
2 U. v. ^' d7 z8 z' Y bool m_bDisableWANIPSetup;
# b' i Y: K5 J" }/ B( Q/ ? bool m_bDisableWANPPPSetup;9 W% l: N; }, x" @3 H" w4 l
1 E* c! v& \5 R( h8 }( R- b+ l7 a/ w3 L/ Q8 y
};5 @5 c# z0 O* h6 T+ M- _6 T
3 n( n K/ Y8 q7 c' I, _2 ?
; u9 f" a$ o+ Z% e( O1 T5 T// DeviceFinder Callback
! K7 x3 }# s6 b6 O9 ]- \class CDeviceFinderCallback
9 N' K( R W5 l" Q : public IUPnPDeviceFinderCallback! y! E5 B% d- C. F8 @( l& @9 X8 n
{% E& p( n& a' e6 t6 o8 L
public:% G2 O2 @7 e& q( E0 a
CDeviceFinderCallback(CUPnPImplWinServ& instance)
; ]& N0 J5 ]1 R O% y : m_instance( instance )
/ F9 G" m( j% @ { m_lRefCount = 0; }
% E% {& k! d2 Z: x" w0 h% g7 h: v P* ~9 v& |$ Q. b
8 B- J! b" _* r$ e+ U
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);! Z2 k) G: v5 I6 r" d6 Y
STDMETHODIMP_(ULONG) AddRef();, G o) Y7 a) \. n4 X* O" e
STDMETHODIMP_(ULONG) Release();) }- o8 M5 h. C- O6 h5 h- B
# f% U l9 _6 v) b
G0 ~( D9 T% `8 Y [
// implementation0 {; _3 T# M& u0 G( \
private: H: o- I$ p; q$ \ l- p4 `3 M
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
q- U {% K$ [- \0 O3 H, U0 ? HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
' ~, }! Q- V$ \, { HRESULT __stdcall SearchComplete(LONG nFindData); V5 E M1 S9 d a- J9 w& I. i+ x
- a' q# y h, {% G
2 o& D, t5 X" c/ Eprivate:2 @* i6 b& l: h+ o. k0 Q* ~
CUPnPImplWinServ& m_instance;, {9 @4 D5 e( m% D7 Z" [& b
LONG m_lRefCount;
: o1 T6 K, ~" ~) ? G9 R/ h4 Q2 k};4 ~; b7 D8 A8 K' W" J
7 @. ^7 K- P4 d6 e* L: e4 ]) D0 @! F0 M$ P) z9 t& m
// Service Callback 2 s2 g d x; m
class CServiceCallback9 Z, _8 U; O- ]4 \
: public IUPnPServiceCallback
: t: W$ O `1 K8 g0 }{
8 y8 y4 Q7 }* M( b4 o+ u0 U/ y' Tpublic:6 D, V' Y6 T6 P
CServiceCallback(CUPnPImplWinServ& instance)
7 W4 L: `! `! N D( y a : m_instance( instance ); z7 w8 G+ W! R* T3 W
{ m_lRefCount = 0; }
- j$ {( K5 n7 [( w- O. A2 t4 \ ! Q1 _* D% } ^5 t
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
& M1 `9 q/ b3 b: X, s% S STDMETHODIMP_(ULONG) AddRef();
6 a* o g$ K, ]: g1 h) D STDMETHODIMP_(ULONG) Release();
$ g/ a: v/ X F9 a% R# e! }" _: p, h$ j( b
5 x/ `" m9 ~ @4 ~/ @; _7 \3 y// implementation
( `, ^9 I; O6 ^ f) j4 Y% [private:
" S" K, G+ c u u7 o* u HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
* L" i( \/ Z9 E HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);8 x4 }" e! x) c' @4 T ~
& K1 R7 j% F7 |, Z% `1 }- K
9 r2 P$ M7 o& U" S! Vprivate:
0 l( F0 e0 e+ p7 Q' v CUPnPImplWinServ& m_instance;6 Y: |- z+ @6 O6 Z; p& ^) X. m
LONG m_lRefCount;
7 E% p& S5 o. @ O' P$ w};
" V# E- }. j1 B* ]" @, R/ j; W1 r. I( J0 C# s7 i( @; p
( p- d' Q& r/ W- A/////////////////////////////////////////////////
; X& [/ j: p9 D
8 t \/ |2 |' y$ ~# Y" h0 o
4 @5 S* u) H7 l. e使用时只需要使用抽象类的接口。
; o/ ?8 W: h* r: ^CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.$ P6 b+ }$ M5 f( Q" q# T
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
; @4 I4 y: e& U- \CUPnPImpl::StopAsyncFind停止设备查找.& k6 }6 u' M+ q6 u
CUPnPImpl::DeletePorts删除端口映射. |
|