|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,8 y" ~1 G& J0 T. C
: }+ n7 o- ?. Z3 P
1 s3 T$ a G: [
///////////////////////////////////////////
& N! q& d/ ]# C, k) [//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.8 h) c( j0 v9 V- L9 a
/ S$ M: c8 P9 I0 C6 |& A: Q9 K
7 M6 c: }8 c# |
#pragma once
* b% _# z; t. o+ U$ h#include <exception>" z( c q& {; V, U
; Q5 J) V/ ~" l. _6 R' ^8 ?7 r1 E
( D! W6 c0 V5 H enum TRISTATE{* A4 c2 S' V: B" x8 m+ ~! n
TRIS_FALSE,
, Z: B# H9 m7 I8 r0 Q TRIS_UNKNOWN,6 f" T5 c( \/ v2 C0 {* g
TRIS_TRUE8 `) Z& e) t8 u) M8 c% E6 T% D
};
& G9 b: r: m1 ] P o7 \, N7 Y% F8 @5 R4 @, ]+ Q, C8 o5 _+ c5 B
1 O" H' H7 N" V; U4 b
enum UPNP_IMPLEMENTATION{
6 `1 G& A2 |% A7 o8 p5 O UPNP_IMPL_WINDOWSERVICE = 0,
1 p6 A( E1 `$ h, x# H f& L UPNP_IMPL_MINIUPNPLIB,' [0 S) p0 N0 C; F) r7 B( v) V
UPNP_IMPL_NONE /*last*/
1 ]3 T4 N* A! Z% w* K0 Y};4 D" E& A0 a& X( j$ h9 E+ b7 ^
& \" j, u/ J% k' _1 t4 w$ h
% D2 n) U7 \2 X
/ D7 J: W1 n0 _; D7 Y, \5 c9 C8 U
3 l5 E5 i1 V# O6 ~" `' U" wclass CUPnPImpl/ T0 s) Y; h, _! _, z& o
{
$ _8 S. t7 [6 J, fpublic:9 A6 }# p I, }3 o
CUPnPImpl();
8 `7 ] N; M" g) m$ n virtual ~CUPnPImpl();8 g$ H' ?, u1 {
struct UPnPError : std::exception {};# Q b) ^0 Q' B6 R4 [# b0 D( q
enum {
) a# z: @2 E- P1 k UPNP_OK,
4 \# e4 `2 p# q, l5 |; \8 N: m UPNP_FAILED,% W4 V- z1 _" b( v' Q- w; r
UPNP_TIMEOUT6 k# F; ^ r3 E# X+ ]) e$ U
};
$ J7 ?" R9 \8 I4 [. k- w9 S
: U, V' H2 ~. A; J/ ~% F6 |7 l* }* l
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;* g0 N% J0 y. B. w
virtual bool CheckAndRefresh() = 0;, b5 \! s3 L" v2 d$ R1 G
virtual void StopAsyncFind() = 0;* [/ g& G9 {/ s6 u6 o+ R! [5 D
virtual void DeletePorts() = 0;
' e4 `. h2 R$ G9 x1 O3 x: K g+ B, W virtual bool IsReady() = 0;) L6 v0 h3 |. K1 ?3 }$ R
virtual int GetImplementationID() = 0;
6 i: N& n5 w: R% O r3 O4 |: G/ b
4 t- e! B a) u0 q void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping1 r9 S- x- v6 y4 N" V5 w
: X* `! V. n9 b5 h9 S3 X: D* q, B; Z" _
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
6 s; v6 t6 m% u! t TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }0 d5 Q6 F Z1 l
uint16 GetUsedTCPPort() { return m_nTCPPort; }+ [& S6 _ h. k) e; ]/ c! S
uint16 GetUsedUDPPort() { return m_nUDPPort; }
5 ~3 u/ d0 V& j( S m8 |
% M! P: a7 Y! O; f3 o
5 @+ y9 e, |6 i6 M/ ^// Implementation, T7 q" M" _5 _7 \
protected:
/ o3 o5 H% q% R/ @7 X' T# s$ S9 J volatile TRISTATE m_bUPnPPortsForwarded;' x2 X% v1 @9 n) H
void SendResultMessage(); T D1 x$ z1 y& K" g
uint16 m_nUDPPort;
: u2 M- I( H# ~5 n# _, p, T uint16 m_nTCPPort;
# |# O, O3 y4 ^) L* n uint16 m_nTCPWebPort;# Y" Q2 I# Q$ S R4 ?% x/ u
bool m_bCheckAndRefresh;( g) [+ P: s0 E1 \0 ^ O9 D. A
$ r" f' A9 J& _: S- F8 m9 [7 B7 p1 B0 E
private:
) j6 l( r" @1 k1 a: l6 k4 p HWND m_hResultMessageWindow;
! r3 N) A2 @/ a5 ?2 ~! G# \% m UINT m_nResultMessageID;
4 F2 O8 V, M r: F$ i6 | U2 c
9 `( J! c% |( z K8 o/ D8 a
* j4 x6 ^+ K* _! F7 x};
8 t( z/ M: W+ ^ b5 D- S
7 a1 ~5 I6 R+ X0 m3 A
% O& V: A% S0 c% A& {# p* [// Dummy Implementation to be used when no other implementation is available" r) q) r1 z1 X6 b# q, P5 `
class CUPnPImplNone: public CUPnPImpl$ N% s* N( |! x; j
{
/ ~9 z9 L$ _; W: Dpublic:
7 B! |# o) N9 x$ G P. g virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
7 t }7 x% \8 Y& }2 K& s virtual bool CheckAndRefresh() { return false; }7 S4 b! w2 M* _
virtual void StopAsyncFind() { }
" E4 ~( O, Y: I) }; u I( Z9 C virtual void DeletePorts() { }
7 \) D' [( \" ~3 ?! t P; T% r* a virtual bool IsReady() { return false; }- P" Q P( ]* f
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }; @& y5 l2 u& F+ I- E
};
Q. i- p# O/ F8 F
0 @% J8 Z* J# _. e' h2 m" ^
+ [+ a, W9 N* N M5 ?2 _/////////////////////////////////////
1 j' o4 V. T5 f3 a% _4 B//下面是使用windows操作系统自带的UPNP功能的子类0 U+ _ y7 X6 S) l1 k6 c% e
' |7 P9 t8 H8 S$ y
! X/ _+ Y- B7 e% L, Z#pragma once
4 }0 B8 Q0 ]; L! ]#pragma warning( disable: 4355 )
|# I; z+ p/ A/ ?8 O
. X h: w, L4 J4 x; Q: U) q
. w# m. ^9 I0 ^, {3 C: o/ t4 D! I#include "UPnPImpl.h"% x$ [5 ], G' @) D( @ n
#include <upnp.h>
1 P$ A* P) q9 t0 s) y, U#include <iphlpapi.h>
5 x+ h. v2 c1 E#include <comdef.h>
4 `& P) `& F9 i8 n#include <winsvc.h>
8 E+ m- R' h4 h' T
3 n& v" E9 [: ^ R
5 x9 g( B, h4 Q1 L9 j; H+ b#include <vector>
, Y2 z: j) Q9 Q# b4 @#include <exception>5 H$ c8 N) e$ {; j0 G% Q
#include <functional>
0 X5 f1 J! I7 U# P) F
! ?% D* S/ G; m7 ~1 `
. B6 N- ^8 b, w* B. p4 P. N: @2 _7 E8 H" J0 r2 D# u: b H' k
5 q) U+ w* Z/ a: G8 z% O* o$ Q
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;4 K; L# L3 ?) J3 f+ g
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer; y. f5 t$ ~, C( }& Z' a. [
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;3 q1 A9 P. s, Z$ ~- G a5 W
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;, x2 j5 Z' N( P; L
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;/ p; F% _- C S2 `
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;. h% q ]" r3 D1 }* S; Q
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;* W- s" q5 U, _
% D! u/ a: x! G) s. S8 N
% e$ X: m$ g* w1 X! x, j1 t
typedef DWORD (WINAPI* TGetBestInterface) (" ] n8 E0 V' L2 e* e3 t) @! J1 h
IPAddr dwDestAddr,% K3 ], Q* h7 W( g4 K5 x1 N# o
PDWORD pdwBestIfIndex
8 B& |* q: ~, ]% l+ p0 C1 L7 z);
3 v2 y# V; q- J+ {4 a- y7 O. u. W, f& n% S' J, o
+ i1 m. N' ]/ t9 Z/ otypedef DWORD (WINAPI* TGetIpAddrTable) (
$ D. q' F/ r4 S" u3 N% l PMIB_IPADDRTABLE pIpAddrTable,
2 q# d$ T# M/ M+ a PULONG pdwSize,
0 ^ A5 R& u: b BOOL bOrder
- J8 ?& e$ @& R$ {$ r. l' ?);
4 A* X& W2 h1 Y; r* ?/ A' t0 h/ |% N8 X# c1 S
" |6 N. R i- a% f) D( ]typedef DWORD (WINAPI* TGetIfEntry) (
5 a: u( C/ K3 a" Z) e& X PMIB_IFROW pIfRow! X5 Z' I' e( Z* S" u
);
1 R! a: W- D4 E8 u+ x( ~ l# m
% x! J0 k4 Z" s9 Z# i8 s% R7 _+ g$ C$ Z* z m5 ?
CString translateUPnPResult(HRESULT hr);
& C. \% K5 _& R& s- l& n# zHRESULT UPnPMessage(HRESULT hr);
0 m% m& w- t: m( o+ K" {5 j$ Q( ^" R7 t
' h2 R' A) G- k
class CUPnPImplWinServ: public CUPnPImpl
5 b. A" v6 B% z0 y6 w% y{% r6 H+ I5 x- ~9 |* Y$ T. _
friend class CDeviceFinderCallback;
4 s9 D0 @7 Z' e, b. |) N friend class CServiceCallback;- K3 }; R* G0 N; Q7 s& {" d
// Construction) c9 {; S$ d- a
public: ?* E+ u# q& l
virtual ~CUPnPImplWinServ();
" N9 t# T( }1 V8 T8 k$ Y! |# _ CUPnPImplWinServ(); ?" S% k2 z' X0 r& I
$ d# A5 b) @- d' g
# P a4 l3 \7 l/ S( r1 p: d! N. P
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
' b* B/ x! Q/ `; ` virtual void StopAsyncFind();
( u% G! b* v( `# K2 v virtual void DeletePorts();
$ h2 C( l4 _4 E virtual bool IsReady();8 Y' \8 `* m2 f
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
- S+ K* e7 x1 T* K V- F5 m$ Q( _4 h% \
! g! a( b, J) N, t: ^. ]% @
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
- g6 D6 Z/ X w+ b // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later; {! o: `# j% ^( S7 e) i
virtual bool CheckAndRefresh() { return false; };
6 c' n+ I+ |: V) N4 d3 w9 N% A2 V! L- w
% }+ i- u2 }# q) \. n6 Z2 F
protected:
6 g& T( h5 ]+ c1 `' L* B void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);3 \: c3 Y, W O, A
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);/ u: z, G ?9 q! q1 o5 @
void RemoveDevice(CComBSTR bsUDN);
* ?6 c/ q( U7 e0 g8 {- h) H, e bool OnSearchComplete();
. f& J9 `: p0 H- d1 R: D' E void Init();
% J# b) L$ v5 q# O# H, p4 [4 h' h" v7 i( q* g
" ?8 ^5 {7 k7 G+ E+ T) d9 @& n, o5 p
inline bool IsAsyncFindRunning()
% X2 W! j0 p9 v9 g: O2 k x! K {
$ U7 Y N: V( w) u$ Y7 z( J if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )1 R/ z0 Y4 L: u# S8 Y% H( Z
{9 N. L& ^/ `/ Q) A1 z. | G7 W8 [
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );: W, y" R4 o# {, X" m6 P8 ~
m_bAsyncFindRunning = false;
% Z# L- I c; B2 v6 S7 T }
5 g9 P9 C; W0 n( q7 V U MSG msg;4 {5 p$ ]& e# V% F2 R3 v! v/ {
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )* ~- @/ Q+ ?2 u( p
{' M! u$ I% b& G* J7 K/ u: m( e& o
TranslateMessage( &msg );
) i# Y5 |; m# s% ] t8 n4 g% } DispatchMessage( &msg );
+ c+ ]3 S. b1 \1 S: {& r* c }
8 Y# N* W3 s; G return m_bAsyncFindRunning;
& Y4 j( ]0 K5 [ }3 X$ ?% |7 b" f5 B' ~
0 g' K+ E# ]8 c9 J |% I) [
8 B; P& \- `* c8 t
TRISTATE m_bUPnPDeviceConnected;. M0 p' Q2 _( r1 M0 ?4 z
& s# {: [2 o7 b4 U3 T- W" l8 [& _: W3 J
// Implementation
, d8 X5 i1 N7 q* b // API functions
9 B" y. U! l0 j" O8 x SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
. x9 B7 |) `5 S i- b% @6 [ SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
6 y2 s( n0 `: k8 @/ U BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);! w: b8 n. n. B: L$ q( L4 r$ J
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
; z) q9 m- w( y8 f2 G1 m BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
% X7 [: \, O- T+ s0 L4 b3 U BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
* f5 W' p1 \; w9 Y8 x
5 t4 Q( l* f/ ]+ }5 j4 h7 A6 d- c8 t F3 ]+ L' g& T
TGetBestInterface m_pfGetBestInterface;
$ C- A# z# P6 k+ k3 @ TGetIpAddrTable m_pfGetIpAddrTable;
5 X N: g& n8 L+ S: V V TGetIfEntry m_pfGetIfEntry;1 L9 S' E9 t% U ?% z3 n+ n
1 Z9 o. X' P5 G" K& z: e
+ V# b8 q* i5 Z* c1 t5 j static FinderPointer CreateFinderInstance();9 k3 X6 {2 \4 y) r n0 x
struct FindDevice : std::unary_function< DevicePointer, bool >
& p1 C) }+ G' K' K {
% j' d* j2 [* C8 i }, N" U" _- z FindDevice(const CComBSTR& udn) : m_udn( udn ) {}0 ~6 A; k' k( S: T0 d, l
result_type operator()(argument_type device) const
+ Z' o# ]+ J9 y" Q! k; J3 m1 W {
) o) ~, g }2 l8 Z3 u, ?( { CComBSTR deviceName;
0 _, b- V' T5 W+ \7 [( S HRESULT hr = device->get_UniqueDeviceName( &deviceName );
: |) u* K8 q( P3 s3 A# T4 \, p/ Z0 `/ }
) c8 W3 d+ w6 A6 G9 D _" }7 ]. C% f if ( FAILED( hr ) )
8 ]1 `) ]8 s( y return UPnPMessage( hr ), false;2 z* B( c1 y; C0 J6 I3 Q, i* W U& v
' f; o% Z4 s, a& F# g1 w# X6 O" O+ }% g2 Q- g6 B
return wcscmp( deviceName.m_str, m_udn ) == 0;* W' Y1 y# a% ^2 F
}+ y; U- |3 D" {" j0 W
CComBSTR m_udn;
* s! [. o. A+ y };
8 w: g' P/ L: f. }! y( ^4 {. C5 [ + R: J# G( ~# @1 t, ~8 r
void ProcessAsyncFind(CComBSTR bsSearchType);
, T, i1 x# O* U J+ G HRESULT GetDeviceServices(DevicePointer pDevice);, R5 U" v$ }5 i5 R5 k
void StartPortMapping();) M+ B5 _* [% M8 ]; m5 q
HRESULT MapPort(const ServicePointer& service);7 Y k2 h& k( F) [
void DeleteExistingPortMappings(ServicePointer pService);
$ @" x. G, \* s) Y void CreatePortMappings(ServicePointer pService);3 G9 t0 _$ [# h3 S$ \- J
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);, o( Q" V1 S) v$ G) I! c
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
x5 O6 Z, w. e; x1 O3 M- ] LPCTSTR pszInArgString, CString& strResult);
* I2 X6 \# D$ G: ^. \ void StopUPnPService();9 ^$ S# m5 M1 Q
3 g0 m: F* h) ~, u$ D8 i/ F7 `
& q: h' F$ w3 C; p$ f0 F- I# \ // Utility functions% S# t/ h! s0 {0 J
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);1 A# `% {; `. p7 K) ^8 x" g, T
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);4 |4 U Q3 f! ]3 G5 u* F2 h. l
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
. d8 n* y C' [, C4 S+ P) P6 w# | void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);0 j2 ^5 d$ \# v4 Q" _2 I; E
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
% e4 a8 U! \: R$ R; t5 i* U# i8 E HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);4 h/ S1 d$ ^% E: j
CString GetLocalRoutableIP(ServicePointer pService);1 G: a# { J( K, }
; h- o7 p, r( h' Q& M7 C
3 R% x9 _8 m. h/ }3 e) h* D- I, S; ], X
// Private members
( E+ M! J7 ^- iprivate:5 x$ O% K2 ]- N; }' L0 c! i
DWORD m_tLastEvent; // When the last event was received?
8 ]7 `) C: {' N" |3 ~$ | std::vector< DevicePointer > m_pDevices;2 r$ @1 `% j( o! {3 G6 a
std::vector< ServicePointer > m_pServices;2 k2 b) f( g: ?; U
FinderPointer m_pDeviceFinder;; f. x Q, L4 g# A0 l0 M
DeviceFinderCallback m_pDeviceFinderCallback;
/ q8 C8 ^& I* T& f ServiceCallback m_pServiceCallback;
( x( Y- w* r4 s' K Q, S* V5 \1 A, {
8 v2 }& h t) P# Q# y) D" l LONG m_nAsyncFindHandle;5 E; T6 D% a3 `& i, r
bool m_bCOM;+ J& \" t* y/ [, ?3 v: v2 I$ H9 F% z
bool m_bPortIsFree;4 v8 M. ~ a- f* ]+ k6 o- k# E9 z
CString m_sLocalIP;
: Q! K0 F* @" }8 ]6 M! t! P CString m_sExternalIP;
+ \! O* L E/ E bool m_bADSL; // Is the device ADSL?
) L7 Q0 D7 T {' ?: V9 ? bool m_ADSLFailed; // Did port mapping failed for the ADSL device?, k% q3 D) d% m) s/ I
bool m_bInited;
1 N, u0 A& I" B$ h8 ]3 ~6 _ bool m_bAsyncFindRunning;
% g) @: k4 ?. F2 n- O; X+ m' y3 j; B HMODULE m_hADVAPI32_DLL;: \0 n3 D8 J# h% ~
HMODULE m_hIPHLPAPI_DLL;
8 |. m1 G* y5 W" v' O/ L bool m_bSecondTry;
( I2 |5 S0 i; e8 U0 X# y bool m_bServiceStartedByEmule;4 v2 c! U5 O# B8 P8 Z: _
bool m_bDisableWANIPSetup;( D& o1 C d. _6 ~5 V9 W# J
bool m_bDisableWANPPPSetup;
4 l+ g% R" f) |( w1 r8 }& Z3 H
! s" ?1 x% a7 k5 I
8 w9 s3 r+ g6 @};
4 o1 a# O1 O7 V/ e. n
% m5 h" @! G! N4 r+ ^! _ S A/ `2 G9 j( C
// DeviceFinder Callback
. G" y+ n! f& z4 U4 ~class CDeviceFinderCallback
! O* {9 O f9 h9 o1 F: [- }& J1 r : public IUPnPDeviceFinderCallback+ w, a$ O" m+ E9 j+ }
{
; ^6 n( o% }# ~1 F! Apublic:
% m5 ^; A, r/ `3 N. q CDeviceFinderCallback(CUPnPImplWinServ& instance)5 I, l3 Y( f( M- F
: m_instance( instance )
4 o1 x( B# Z2 G" r2 y! F { m_lRefCount = 0; }
, f! {% {* h# v o# Y& h L) q) L0 Z0 N7 w" U. a1 g6 q
; l3 P& F6 `, K+ u. K
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
# Q2 q& u8 e# r STDMETHODIMP_(ULONG) AddRef();
# u0 H# F, l2 c0 ]5 D3 t: q STDMETHODIMP_(ULONG) Release();, C; f+ x; N: R3 E, B3 s
2 [# U" d& D; A o' f6 [6 u
f1 f3 U& i# d. G4 X// implementation
! `! t. r% [; T( Zprivate:: C. w. S# H! Y) {, m
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
; h4 {) |6 c" V! _8 \, G HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);9 {/ K, M% V* h+ }7 e
HRESULT __stdcall SearchComplete(LONG nFindData);
4 v4 x) {- A6 j) a9 L! e9 V/ c$ T+ v
- z& S$ `: a! U- d! D% n9 V
6 e3 s! z0 j5 }5 Wprivate:, `( I2 ?, `/ o. g
CUPnPImplWinServ& m_instance;: @$ d8 W4 Y4 x
LONG m_lRefCount;
, h) Z- @9 ]5 c9 {$ H. j1 Z- h$ {};
1 B0 Q" N' v. O4 e' ~
+ w2 `. ~, W* v( u8 A: ?" M" x% e$ O
// Service Callback 5 M; \( I q- E
class CServiceCallback: Q8 @) Z5 h8 t1 W$ x8 K
: public IUPnPServiceCallback @3 V+ Z# B" r/ ^9 v9 S) Q3 K8 |
{0 S4 E9 K3 {' x: Y, o3 ~" u
public:0 U1 x+ ^9 ^0 F5 V) V$ B! Z5 k
CServiceCallback(CUPnPImplWinServ& instance)
* q1 P8 X5 ?7 e) ?0 x( \- q : m_instance( instance )
* U4 Y; W. M9 F4 s$ w$ s( z, N { m_lRefCount = 0; }7 G) W8 E. ^$ f1 |
/ Z2 C" {3 v6 A! U* ~/ b
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);0 c2 L/ m( j; Q: A/ \- a
STDMETHODIMP_(ULONG) AddRef();# I. P% V; r; ]0 F; O
STDMETHODIMP_(ULONG) Release();
8 x- p3 ?: [$ k8 Y) w* A$ g' x% r7 n0 @
- h7 X w! h( n) P* P( t" R
// implementation
5 Y8 v2 s$ l& I* K; j* T7 U# \7 Kprivate:$ _% Z2 z6 V! h: C0 e9 A) s9 M
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
) `" ~" |/ t% @4 u HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
( I& B6 G$ i) t/ Q' B0 u8 r4 ?$ }1 \- y" N$ l1 F1 L3 A0 h/ b
# G: s- E/ Z. p
private:; B% Y2 E9 u; i/ k! S: d) F
CUPnPImplWinServ& m_instance;
" S- v8 q: L; x, v m LONG m_lRefCount;* I9 l. D0 v r2 O0 O$ ~ @
};% z7 x" ~4 z7 z, Z
$ ^' @! b: d4 y, N" m/ b: D
) G. Z( T3 F; H- h5 q/////////////////////////////////////////////////
- u8 s$ R9 K3 x) _6 g
8 m. @8 Y- n+ c: K/ h! g- r. `8 I; G7 x- v( S
使用时只需要使用抽象类的接口。- Z" g) C' G% H- ]7 \6 C
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
8 q4 C/ v& p$ Y B5 Y4 jCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
: c( Z" \ C: g( l+ H3 d) WCUPnPImpl::StopAsyncFind停止设备查找.
$ w9 S# A' \! qCUPnPImpl::DeletePorts删除端口映射. |
|