|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,- e/ `: a/ Z1 T: s, w
$ ^% L1 M- i; A4 X
" D8 F [& R9 ^8 b///////////////////////////////////////////- q) V0 B- t* d5 q6 ]
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.% f/ w! J" i! v$ {6 l f1 [
+ [2 W% k2 l. ^, q( W5 u
( R3 m# g5 w2 T% k& ` ?1 S6 P
#pragma once% T5 C: F3 Y+ @% g% i
#include <exception>
3 w3 K" y5 ^1 K, V$ y. q9 f/ G& K. }9 K c
8 l9 K9 Z# m* V! d& \% F
enum TRISTATE{% X d3 W0 l _% e4 B
TRIS_FALSE,
9 S5 D( a1 k+ A# E( q TRIS_UNKNOWN,
- Y5 r4 H# |2 _4 Q' j TRIS_TRUE6 {% D" c" G$ Q" D# f3 s
};' H; v, k4 Z1 l9 ~/ }
( ^) J2 h9 O# i; ~$ b% V5 a( a1 G
. l3 P* f- Q4 e! k' l" B; C
enum UPNP_IMPLEMENTATION{4 j- `0 J$ i& I, `* P% B t$ C. |
UPNP_IMPL_WINDOWSERVICE = 0,7 s/ y% z8 X0 {' S. @8 G8 w
UPNP_IMPL_MINIUPNPLIB,
3 E/ d% \& u" ]' L. e3 L UPNP_IMPL_NONE /*last*/
7 O$ o. u1 a' w0 u/ @};9 ?2 o0 `( c: K9 c* ~
T; T( G4 u% c B( k3 r" {
* s" S& m0 P! d3 v* T! I# @2 a+ c& Z4 `, L; L6 f
; s: E. P @2 n. }" x
class CUPnPImpl
% g' U% L9 \ q2 A2 M{
; ^ Y5 H% A n4 \public:
: e+ w$ v% N( v! y CUPnPImpl();
. i2 P. I7 G4 ^. w. x virtual ~CUPnPImpl();' J, c& e* C+ ] g8 S& i# B9 I
struct UPnPError : std::exception {};$ b- f0 t2 i, K; Q' `
enum {+ D0 A2 ~, n- T8 K
UPNP_OK,
4 d( c( h8 K3 v4 w UPNP_FAILED,2 h; S' j P: l% y) o" g1 m
UPNP_TIMEOUT
6 ?6 x# s# h7 A };
8 ]3 K, F' y) c% |! k
. H% `, N4 h" E2 x* K4 `8 O) \; I( r
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;* V) W4 z0 v% Y" Z" }
virtual bool CheckAndRefresh() = 0;& b6 l0 J# N0 @
virtual void StopAsyncFind() = 0;
3 b9 ~2 P% n' G& B& y/ I3 o) U \ virtual void DeletePorts() = 0;
6 P8 a# N+ O% w. p- B1 }5 C virtual bool IsReady() = 0;
1 P+ J' p( L% a. @( B virtual int GetImplementationID() = 0;
" m. F9 p3 N) Y& g
1 }4 W/ u4 g- b4 G# v2 S5 `' @ void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping, M4 k- W- O3 c2 t* m
. K+ {/ b* j8 F: t5 O' H! e! b
% `& ^0 Q% v/ r void SetMessageOnResult(HWND hWindow, UINT nMessageID);2 `$ ~- P8 n6 b( h! E3 x4 g0 [
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }( T; m: S2 Z7 c3 Y
uint16 GetUsedTCPPort() { return m_nTCPPort; }
/ K8 K) H- }" \* v" [3 s uint16 GetUsedUDPPort() { return m_nUDPPort; }
, Q( ^1 N. J5 ~% M6 N3 z
7 {! m1 m* D/ F, N' x% v/ S
4 U5 e- e( T" N" e+ f- @# @// Implementation
- a6 i! W H1 I5 ^protected:7 n- _/ c( o" e" ^4 y9 J) O2 S
volatile TRISTATE m_bUPnPPortsForwarded;
/ P8 m# a3 F# I1 A( F( n) o' W void SendResultMessage();# [; n, e6 k2 P6 U/ U7 O
uint16 m_nUDPPort;
$ ~9 N, L- z8 k0 H uint16 m_nTCPPort;6 R: w) y+ w) b
uint16 m_nTCPWebPort;( g$ `6 _& v2 ]; w, r7 q3 s3 r% J
bool m_bCheckAndRefresh;- J% p; K# \6 e2 Z: [( _
' k1 Z6 i* i6 }
( {/ L6 N1 ?" t3 q& y
private:
% F# m' ]) r: Q9 _) ] HWND m_hResultMessageWindow;
5 C6 r; Q; ^5 @, `8 [+ y' S UINT m_nResultMessageID;# Q0 [: l' S4 y$ j$ H
/ ]6 V H! O3 V, f' ?8 [) e- a6 V" F, j: f
};$ i" g$ w7 j/ I/ q6 ]) Y
. i8 E; l O% ~
$ U1 J& O/ R( |$ ]' Y// Dummy Implementation to be used when no other implementation is available
, Y3 D3 H1 `- [! g! @+ C9 Qclass CUPnPImplNone: public CUPnPImpl
+ V: ~& q p9 S* c{
3 J$ S |; ^! cpublic:1 P! X5 l5 R+ D
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }9 a7 |4 P0 k6 T
virtual bool CheckAndRefresh() { return false; }: `' F: `* v. U6 l4 M
virtual void StopAsyncFind() { }
4 U6 ~; z: n$ B* m* m virtual void DeletePorts() { }* B3 ~) Y5 y0 P |, T1 g
virtual bool IsReady() { return false; }# w$ P" v' _$ u# \; Z
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }2 D5 a& _" F% |, r
};
! l& X7 S3 |. w8 o# {2 q! U
4 C! o4 j% c& u' w- B7 z( C5 z. m, w" W0 {
////////////////////////////////////// |+ n( T$ u' E7 \, p+ I, x
//下面是使用windows操作系统自带的UPNP功能的子类# B! M) j: b* n8 Q9 D* ]! H
* J! `$ m: d- Q: h: [& X( R" `' }8 C9 r
#pragma once
: `# \8 ~! F5 D0 u1 ^ s! b#pragma warning( disable: 4355 )" _! c+ k; L ]7 m5 T
4 S6 s( K9 y+ u ^+ ^' Y8 q. A
/ h8 `1 v! ^: P. d _% X. v" s
#include "UPnPImpl.h"! F. j" z" D# b
#include <upnp.h>9 o; q( N& n: v% }9 a' M
#include <iphlpapi.h>
4 J2 n8 H/ f7 R2 R#include <comdef.h>: U! j' D6 ?" ?+ |" z' ~' ?4 b
#include <winsvc.h>( g. w& x$ P R2 Z
0 r8 b1 L5 J8 G2 |, `/ M1 c
1 D. U1 N' g. j4 Z1 k; f2 Y/ f0 i! z' [
#include <vector>: X3 g) Z9 E6 E' {7 a
#include <exception>$ O, e0 H4 C5 O/ ~' M
#include <functional>
2 {, Q9 b( ]! e3 t
/ T1 A4 }. {7 K* l9 W# l8 E- W( U: h5 h, k9 L P9 x3 }
9 H( Y( S, A- P, \' R# a. A! }8 H1 N4 ~2 h! B3 ?8 \1 p
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;; _4 C) @; I& G! A8 Z }1 R
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
; k- Q, n/ i- U" I: H0 u9 j- v( Dtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;4 |0 V3 n6 h' K& N+ {6 r3 J
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
+ @6 G7 E8 G) C: E+ ?. dtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
3 m- C# L: i6 \typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;" J7 t+ C/ Z- o7 d( M4 a. R5 \( j$ K
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
/ Q% W( e/ Q) C2 h. r7 L& k, h0 w* n1 l( J, U( H
) ~) h* m( j9 Z+ h' _. u9 Ptypedef DWORD (WINAPI* TGetBestInterface) (6 c( V# y, P8 A# x& ?/ }- J$ U+ s
IPAddr dwDestAddr,
, u' e* D2 f/ y z- t6 H/ H/ r, g PDWORD pdwBestIfIndex. d# p A1 z9 Z X8 d) L
);( i [8 C+ H: V9 `' c9 n
( d+ M3 |. [& s7 M
; m4 D8 d5 a4 |2 T5 ?1 }
typedef DWORD (WINAPI* TGetIpAddrTable) (
1 R. R6 M; y: u5 ~7 i- @( f PMIB_IPADDRTABLE pIpAddrTable,
. Z( o; i$ f1 q1 Y7 h* i& U PULONG pdwSize,$ N- G) e) t, W O# E9 p
BOOL bOrder
' ^4 {! k# p: W);
6 r5 u/ W5 r. M8 q5 w& w2 a" U% S2 Y2 M+ L# ?) x. `0 S: I! W
; M0 U% V2 R* V/ v; k
typedef DWORD (WINAPI* TGetIfEntry) (
1 ?6 ?2 I6 [2 L- Y PMIB_IFROW pIfRow
' N- n! d1 i7 U, l' D/ b5 z6 A);8 [$ d- o$ Z4 p, U' U L# M
& P7 A3 m# z2 T6 v/ W5 K4 Q
& g& x4 ~) j6 r- p# f
CString translateUPnPResult(HRESULT hr);7 z2 F. D+ s5 r
HRESULT UPnPMessage(HRESULT hr);
' H! P6 n2 U3 W3 u- \
- p; k! }8 R+ R# c# D* {2 m
/ t. i+ b( }+ s, oclass CUPnPImplWinServ: public CUPnPImpl
; _: p0 Y9 n% q! }' q0 I0 V{, s9 ]/ D' J1 Y) w( [
friend class CDeviceFinderCallback;
; G& D4 x/ h* t/ V! @; {! e2 e friend class CServiceCallback;
- Q/ ` f. y: q7 b0 c% T// Construction
, s3 a8 a' n }0 |" qpublic:
8 T6 d! b) S6 v" U; W. p virtual ~CUPnPImplWinServ();
5 s+ |' k7 Y; H) Z3 f6 e CUPnPImplWinServ();
# r+ w0 l5 R y& ?3 b$ d8 m, h# n |* O" s9 O9 O
7 d1 M1 Z5 C l/ Z2 Y virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
# l1 i. R. L) X virtual void StopAsyncFind();1 k, U: {/ _2 H* n
virtual void DeletePorts();/ ~1 {, A. h6 @4 X+ a
virtual bool IsReady();2 I* H5 E8 r6 Q3 ?
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
7 O' A7 F' \& I: n- h
7 _0 C' u+ \! Y- {0 ~" W% z5 p5 z9 T
( Y2 ]7 w0 X3 w# G // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
( s, b# n- L y7 P! X // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later! b. Q* o* W3 a# V4 d% e
virtual bool CheckAndRefresh() { return false; };
5 o) V3 p) a$ a4 g# q8 Z6 M; r, h* |
$ z3 J7 J$ v* j# V3 Eprotected:, A0 y5 ?2 A" }" b @9 \( H+ I. {
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
# B( z/ r0 W! g; ] void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
9 V6 z! B( J: C8 }: r/ q& f void RemoveDevice(CComBSTR bsUDN);
~! {9 B! i' l9 ` bool OnSearchComplete();
- e# t* p- ]7 y void Init();
" {# x! u/ {+ S5 I" l
! ~8 U" ~) s0 D8 H; A, D4 W' w3 h4 l: \$ C0 ]- x8 E8 ^8 x$ P
inline bool IsAsyncFindRunning() 7 A- e; B+ w i) y$ p6 O# U- ]
{& S7 W9 \ `6 G% {* `0 U! q
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
+ D5 j% R4 E/ b {1 r& y/ j7 ^- R6 q+ _
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
5 x# p; |" B4 e: }7 w } m_bAsyncFindRunning = false;
/ A, a0 ~5 x! X& ` }/ ]4 i7 P: R5 P1 _* k3 A
MSG msg;# A' X @( o* o
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )3 q- C. v( L+ p2 M
{
) G' F# w9 ?' P6 k" _. k* b TranslateMessage( &msg );0 ?8 Y5 W# \+ \7 w4 E+ U
DispatchMessage( &msg );) j; Q7 M+ U4 [7 h3 G% a, v- A
}( V3 I" O& L' y7 g9 M/ z
return m_bAsyncFindRunning;# N z. r; @: |: U C
}
' U3 N) E3 _# b) e9 Z; x! N% b( i$ w: f8 R9 o, {+ y% a. T
) F0 e4 C: X7 k
TRISTATE m_bUPnPDeviceConnected;
) v6 }/ \9 b+ t: s( G9 t/ ~# z e* ], r. l
4 K6 L/ |# K* @7 k5 G: d
// Implementation
5 S0 K+ w' N9 ]! [+ b // API functions
6 i; k: \; `! C4 n8 t) T0 }" C- a SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
* m: S6 |" `: n8 m! l4 N# G SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
. o% C& ^# ^8 B# A1 q) ~ BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
1 U! e& J I4 p) r7 Z8 s2 y( W1 C BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
+ @+ V+ U8 ?" r* q BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);7 j" q, {. M3 N% X- ?: L
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
! [5 A+ E9 L$ b& F) u* l1 x% ^# q, U1 v% f% i
8 m. Y0 C9 s+ H% a3 U" S2 _ s0 w TGetBestInterface m_pfGetBestInterface;% h7 q4 }. P, x/ T$ r. x
TGetIpAddrTable m_pfGetIpAddrTable;! J3 q5 H' t; W7 x9 T' ]
TGetIfEntry m_pfGetIfEntry;" o l0 O7 n3 w1 g
- p3 G* y3 c! n' b7 m$ v; _
" o K, r$ g! S! |* b static FinderPointer CreateFinderInstance();
/ g, S- | T1 u% C. M" h struct FindDevice : std::unary_function< DevicePointer, bool >
7 j0 N' x* c8 x" F- b {/ k* L; B v4 x1 L) [
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
3 Y% l# @% T/ M$ `; [! B' n3 ` result_type operator()(argument_type device) const9 T) W {3 d4 Q' p2 T" A' g. e
{
. B1 x0 u8 o* a2 l CComBSTR deviceName;$ l+ ^1 @7 [5 \/ M% u
HRESULT hr = device->get_UniqueDeviceName( &deviceName );& G! U7 R; V% s4 u, F8 z( E
; C" X& |: L( x+ @
2 s5 H% f8 e$ }8 W9 ~0 N! S' a if ( FAILED( hr ) )
w% j4 \6 o! @3 H% w3 @+ i return UPnPMessage( hr ), false;1 r4 S- T) k3 y" k: x8 S& E, c6 Y
) X3 W8 E; ^6 K4 U2 {( t: R/ o" t4 k3 l9 l! G% _
return wcscmp( deviceName.m_str, m_udn ) == 0;
5 ]6 q" `+ l) p }
9 q9 {) {2 y" }2 ~ CComBSTR m_udn;7 t9 J" D; T0 \: S3 t0 e. G, ?
};
1 Q$ h" Z4 }3 N5 V/ {: J
2 l l( J# ?' U2 P, N9 w void ProcessAsyncFind(CComBSTR bsSearchType);
2 U9 o0 K: g4 g; J% p HRESULT GetDeviceServices(DevicePointer pDevice);; k5 r6 u' V1 t! R$ y+ k
void StartPortMapping();; [: |, Y& g8 D4 i4 q! I
HRESULT MapPort(const ServicePointer& service);
. \: V$ r* i" P! z3 k void DeleteExistingPortMappings(ServicePointer pService);
; S' _) K/ S( @" D& C) G9 ] void CreatePortMappings(ServicePointer pService);- Y: v0 Q2 ^3 R% h. {7 K
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
; S3 a' L8 N$ p& r8 b) Y HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
9 b4 l# b1 X7 b* L( j( u0 Q LPCTSTR pszInArgString, CString& strResult);
: b7 N' k% d/ i void StopUPnPService();) Y. x/ ~) |' Z$ `( Z4 w
. A r$ _1 T+ s# t. ^7 `, `
' D1 V! n1 w+ i" _ // Utility functions
3 O5 n, c# T3 F0 g ?9 `3 X HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
! K" M& U7 R5 ~+ y6 X0 \ INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
1 q: F( |$ E7 i, h INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);7 X" i% Z! M2 @
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);5 Y. b a, u. U/ p4 H$ G
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);' ?* h4 m& c$ m' b
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);$ b' j% g7 i' u! C- v$ h& r @
CString GetLocalRoutableIP(ServicePointer pService);. H0 m5 f# B2 U0 G9 ~
( ~7 f# Z! y# Y1 b& E$ I& g# t5 [- u2 }/ V: W4 h( y1 A7 [
// Private members
+ r. R) N1 w1 K; I5 w# B( ~5 z/ O+ Gprivate:
2 M. p A; u T' m' e DWORD m_tLastEvent; // When the last event was received?
! s- Z! Z- n5 X std::vector< DevicePointer > m_pDevices;2 N5 a1 J/ n) ~8 r' S# [; z6 F2 w
std::vector< ServicePointer > m_pServices;
6 m' S( F! N8 [0 v FinderPointer m_pDeviceFinder;4 u' U' F, A7 k5 j- Z
DeviceFinderCallback m_pDeviceFinderCallback;
8 U) N3 K t) \4 Z4 a* ^6 e: A8 g( k ServiceCallback m_pServiceCallback;
. A% b, F$ L+ j" U" ~1 d* {- F6 V. Z6 j. Y, ]2 t+ J6 Z @
* \1 N3 Q4 ^; u9 {" l9 u
LONG m_nAsyncFindHandle;8 r/ q3 N* p8 S$ z1 x+ K7 u0 x
bool m_bCOM;
; W3 W$ q: V. n! x bool m_bPortIsFree;
7 ]/ H: r% v, U% S9 s+ I3 q& }% |) g CString m_sLocalIP;
, r4 v- I: h C- L CString m_sExternalIP;& y5 p) e6 U Y+ b! |" q
bool m_bADSL; // Is the device ADSL?& @' A+ r% m- X# u. q
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
# h# F+ q, k, v+ S7 m bool m_bInited;5 A- G% I' I& {
bool m_bAsyncFindRunning;# d' F% r2 S7 C3 C
HMODULE m_hADVAPI32_DLL;
) n/ i8 P; |+ L( N/ i( d* H( v HMODULE m_hIPHLPAPI_DLL;8 r' X2 J0 M0 w1 x. F9 K
bool m_bSecondTry;) p5 {" f. Q/ f( S$ P0 X! k
bool m_bServiceStartedByEmule;5 G- z1 Q9 y0 x
bool m_bDisableWANIPSetup;
$ S [% w' M- k: b& B" o bool m_bDisableWANPPPSetup;
( w5 ~# ~+ j% J: z& k0 T. T
0 c' c, @0 r8 d9 g5 d7 c& i5 W+ s
! }) B& F$ X! h0 v8 Y0 X};
) j& h/ `$ M6 b; @0 J9 B3 p( d. Z. y1 U! G" y/ t5 v) b, i
* U( f2 o& T1 [& W0 q// DeviceFinder Callback; a/ ]" \( j" @- E8 R) ? t
class CDeviceFinderCallback
- z6 ^' x" @; I% L : public IUPnPDeviceFinderCallback
& d- B/ |1 s9 V5 k8 B5 c{5 N2 @6 a8 y- M. w2 `
public:5 g( _4 L: y, I5 E
CDeviceFinderCallback(CUPnPImplWinServ& instance)9 M$ P8 C! \- n e
: m_instance( instance )% I. W( R% h u2 J* Y
{ m_lRefCount = 0; }$ h5 Z2 K8 C7 L" \+ ^
0 J% i1 x/ U+ X, Q2 w
9 G7 a# G4 X% [* E" g% u STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);, R+ G9 a+ A0 ?0 {& G4 d2 ` R/ c
STDMETHODIMP_(ULONG) AddRef();
/ u e9 D }% @+ g% U! d STDMETHODIMP_(ULONG) Release();
! i a& t0 H% G- X
% h0 O. t# z- }) ?: ?8 L5 e; Y( ~- t. d# J
// implementation
4 Z; V" _5 B5 n G! a2 pprivate:
7 r6 M' ~! ]- u: ~& M/ {: H HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
6 i \6 m$ p8 Y$ X6 O w% T! K/ x HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);/ b1 g5 }) ]$ G9 U. I g' `# `+ k% E
HRESULT __stdcall SearchComplete(LONG nFindData);# |/ n2 _! f8 m0 b, H: B
: i, a4 M1 [, n' H# r/ p6 F G* Y
# q% A; n! Q3 R" Q' ?" g/ T6 vprivate:
1 R m* |. R/ Y& O) R! @+ x# f; G CUPnPImplWinServ& m_instance;7 w; w% r, m. D0 e0 w" b
LONG m_lRefCount;
! _6 q+ C! Q! c9 A};& T7 @; H1 h6 `( i
6 j# ~! ?! j" v' }+ W9 b, O2 [5 B5 d# |! ]- F
// Service Callback
; t# ~9 \0 L+ p: u% Uclass CServiceCallback) O1 ^+ y9 j* |0 R- t) ^$ M7 M' j6 C# K
: public IUPnPServiceCallback. D: B6 a6 n& X- f
{: g4 I* n9 m, j' c2 E# s* C
public:
! d* g& [9 T% g CServiceCallback(CUPnPImplWinServ& instance)) _ I, y3 T) s" B3 d9 H
: m_instance( instance )
! p8 E: i: o$ b7 j; r9 N { m_lRefCount = 0; }6 w& s" r) y# m/ r, \! p5 _
7 w1 a w* i( R1 e7 p/ a
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);3 t/ l! o9 \7 x" z( a
STDMETHODIMP_(ULONG) AddRef();! ?% G% Y- L! p* G1 F
STDMETHODIMP_(ULONG) Release();. _' N* v& s; \; U6 K
' p2 Z% k$ @; P. a! Z4 r2 [( J2 ^% o
6 m7 n' \# |$ b; X" c// implementation9 o; Y3 }. [! c0 v7 U3 a
private:
9 v) ?2 \% R1 I' r& ]% K8 _( G HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);# R I3 ^* S$ n; `
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
& |/ n% H: P* }4 y5 d. K: A4 _/ D0 R* n
0 e. C# G6 b% }
private:7 e0 V8 |% d/ |6 C
CUPnPImplWinServ& m_instance;/ ?# N9 y, V/ o6 ^+ X# M
LONG m_lRefCount;
9 j9 a0 }# r2 H A$ j+ g2 X};' ~8 ]+ Z) I ]8 ?, C3 |
. D, a! j- j5 [! R4 s9 E/ j9 d% \& E$ z$ V; U
/////////////////////////////////////////////////
3 f9 s, x' I9 m1 _6 t+ R9 V3 r
0 \: [. I) `3 X5 \4 H, K2 P0 g0 _+ P$ X" d4 a/ C& g" c. W+ g
使用时只需要使用抽象类的接口。
$ R8 X0 h9 m0 n" Z8 |+ Q8 a% NCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
7 H" V8 K+ |3 Y( W" NCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
% B8 s+ W2 B- KCUPnPImpl::StopAsyncFind停止设备查找.9 L. Q/ Y# b" ]4 K: Y; ?" Q4 ]
CUPnPImpl::DeletePorts删除端口映射. |
|