|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
7 S; ~# `/ G7 W- q# K
, |- p& e e h9 c( S6 l0 @7 G: |( E$ U+ W2 ~! Z( j4 Z! l
///////////////////////////////////////////
/ H3 y1 B2 e& O& j* C1 U//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.- M& _4 v6 H [1 R, s; I# V- Q
+ b7 Z% y7 l X1 `/ P, _
% }( ~3 A! ]. x+ Y+ W#pragma once6 j( w* R9 w T# J2 t5 B
#include <exception>
9 E( d, ~# v3 s* G# n; p* M& {' E- V9 d' W, D- o
% i |' {+ i b# O9 _# X4 s
enum TRISTATE{
$ U% p. X2 s& A0 f9 N: S9 m( ` TRIS_FALSE,
$ Z; d2 R6 _, S1 D( P TRIS_UNKNOWN,
3 C6 T& u3 d/ t3 \, O TRIS_TRUE. ]: K% u8 T5 _% A9 \5 c
};1 s) H# b9 ]3 {+ p; B' V8 T# {
7 y8 K3 d3 }0 l0 J: P/ [
! q1 e7 l4 [, J0 U( r2 k I& Ienum UPNP_IMPLEMENTATION{5 E/ K3 C! p E) C& i
UPNP_IMPL_WINDOWSERVICE = 0,
# P6 f. q/ o+ \ UPNP_IMPL_MINIUPNPLIB,
`% b1 H) k* \" V, @7 { UPNP_IMPL_NONE /*last*/( z7 @3 L: h4 [
};3 j1 J% |) A/ }0 f9 b" W
' i8 _2 x; N. K" g$ \
( o' P) {* K# g% h( d" S; A* W
7 a# G5 @" e) g0 m) z" Tclass CUPnPImpl
8 `* Y* | O7 W# G7 O! {{2 k! h3 n! s7 Z* h) ~0 w* G3 q
public:; L _" a4 e" m8 w3 y
CUPnPImpl();
- G0 L/ W5 T* d- x- { virtual ~CUPnPImpl();$ L# D+ i! d0 ?1 i5 X
struct UPnPError : std::exception {};' ^9 t) S) l( V) z. S8 |) h
enum {
. x, j( k) ~$ v; @ UPNP_OK,. ^$ ~5 R! ~9 ~( J, h0 \1 m
UPNP_FAILED,
0 ]% D! P7 L5 Y; R$ h* g1 ? UPNP_TIMEOUT
* A0 ?" O) N* @8 d };0 ?7 j% g% i: B& O1 k
% W9 f8 q1 W' r8 G8 @
2 f9 ?' t% d( G' h virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
4 n* u; G1 Q7 n3 [1 C- \% q: C! o virtual bool CheckAndRefresh() = 0;/ a' a+ a; j- _3 k; p& x
virtual void StopAsyncFind() = 0;
* j' @# o6 p8 t9 N; h9 G6 i/ [ virtual void DeletePorts() = 0;3 v- ^- Z& Y8 f3 h6 t/ X
virtual bool IsReady() = 0;
; L4 q/ h2 S/ C' T virtual int GetImplementationID() = 0;
+ ~1 N9 a" k; m* ?
) b; T( b: c. {6 O" E7 C" X. {. c void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping5 d, K" I; K' q4 X
' H5 I0 J; }. G7 c
- y5 h5 A$ e8 L void SetMessageOnResult(HWND hWindow, UINT nMessageID);" L8 A O# h$ ]6 L
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
0 L4 S4 F; B5 l0 K; Y/ x1 h uint16 GetUsedTCPPort() { return m_nTCPPort; }
2 V6 y6 G+ T7 l6 w) J uint16 GetUsedUDPPort() { return m_nUDPPort; }
* O+ r( [, n' g# M) \7 Y( s( k1 l$ p) t* M
& l# }1 d) Q8 \4 Q4 |
// Implementation
1 S0 o$ p S9 T8 j9 Bprotected:
8 f. j& o- @1 \8 F; Q volatile TRISTATE m_bUPnPPortsForwarded;( h+ D' D' v5 {6 c% F* z$ l
void SendResultMessage();
9 P# ]7 C H& n0 w uint16 m_nUDPPort;) O" {9 J+ A% N9 S$ m' O
uint16 m_nTCPPort;: w' i) n; U" ~( }
uint16 m_nTCPWebPort;- `0 J8 q# \3 q4 l
bool m_bCheckAndRefresh; o$ q% ^2 \# {' g w& a7 q+ \
9 f x E: Q- N( P% S
6 U* }" J' J( E$ s
private:8 G9 v* o- B+ [
HWND m_hResultMessageWindow;
6 U/ E4 S1 C p& { UINT m_nResultMessageID;
. J0 b. j2 M# G U: N4 \' ~: T* E% \/ W3 E( h7 W
0 t1 V/ Y; p0 m" \" C$ g$ d$ B6 j/ D3 u
};
) A+ B# f, X. N
) h; p3 N* ~1 ~/ d2 S9 c1 s/ X
( A+ a, X7 X: c2 S// Dummy Implementation to be used when no other implementation is available l0 n/ X \# v1 B6 ~
class CUPnPImplNone: public CUPnPImpl
$ t; _+ m4 l2 c! C1 X{
8 x5 d2 H9 d# V6 f$ a6 Cpublic:# c! e/ d+ `. e- j
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
1 j; ?# `% L1 c virtual bool CheckAndRefresh() { return false; }
! u0 T: `7 }5 O" R0 K2 x virtual void StopAsyncFind() { }
u$ P0 x ]2 d [$ r2 ` virtual void DeletePorts() { }
3 n: d3 T$ J( g. y virtual bool IsReady() { return false; }% Z7 k$ e" }$ A5 S; d
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
) w9 X( ]+ ?- P* o, W, V};6 l& K. ?/ H' V3 j& q9 ]
* ~; } o% b8 O7 |, i3 x3 k$ `1 }
% L/ V% \+ `5 \) {7 o/////////////////////////////////////
" c. O1 l4 Y+ ?2 p. l//下面是使用windows操作系统自带的UPNP功能的子类
9 |! }1 r) @! c. w$ y' C
' ]* I8 d. c5 v4 q* o! o6 W4 i3 j8 ~$ Y: @* d. z8 m4 u2 z: F2 \& L
#pragma once# u+ D+ p$ [0 D! M, M
#pragma warning( disable: 4355 )
# w! O+ |: p! O) t2 y" [" a8 T: e- g' }2 W/ X. A, f
9 d$ Q! ]" _6 Y0 y& p
#include "UPnPImpl.h"2 h6 u& Y8 m/ |& O2 d, ]
#include <upnp.h>
4 s, I6 x4 `. t#include <iphlpapi.h>
! i9 Z% P o. c; D- g#include <comdef.h>$ [4 N1 c$ g! L3 l- R C) I
#include <winsvc.h>, k( \# H# C3 j& u8 a& Z* z
7 s0 E8 W8 Q) E2 u1 \- Q
; x5 p4 S6 C7 l& Q* N
#include <vector>, E0 ~, \3 B; Q0 U' ?% Z* I
#include <exception>
M) Q; O9 f( _( R: ~5 o#include <functional>
2 H# t) K' b1 D# E. p! `/ k# C4 h X# s( v
: y3 g& C& I9 [- ^. F* ^8 @0 h3 W' ^% h) J2 Z0 n' p& @5 \- h
1 j8 Y2 Q# u8 n; r' Mtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
+ \$ g" |6 ^+ e7 _; Htypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;. L- {* _6 \# g, `4 j% y
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;: w: r+ F) {$ V- J. p
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
# `) ?8 ]3 |/ I! L- btypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;( Q, u7 ~8 Z- J3 v+ J4 z9 k* W
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;2 c; k9 c/ l4 B8 ~: ?
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;& L& B! K- a- V$ u: @% } F' y
6 a1 g6 o4 n/ _; Z; G8 c7 ^; N. M! W2 z6 A; h
typedef DWORD (WINAPI* TGetBestInterface) (
" N; m) ~* v6 D Z8 U IPAddr dwDestAddr,
' O" q5 u4 o# ~- k% g PDWORD pdwBestIfIndex" z2 [) c; _7 Z: [
);
0 v8 l2 K( f# x# N/ l$ Q9 F0 ]) z, n9 F; x9 e- t
: |* i: |$ g4 `typedef DWORD (WINAPI* TGetIpAddrTable) (
' J/ W" {/ n3 S3 J2 O3 v4 Y PMIB_IPADDRTABLE pIpAddrTable, g) E1 V& T+ e* O, @
PULONG pdwSize,
# M+ N7 f+ F" {, [! l% i BOOL bOrder/ t7 f$ I' h6 N% G- O
);
$ y5 v7 N( p9 G
; N( g) V5 J+ b3 y- l/ k& s7 q4 s2 L8 [
typedef DWORD (WINAPI* TGetIfEntry) (; i$ ]. x4 W) f: v' G n
PMIB_IFROW pIfRow* n/ i' E! Z6 m$ p2 v& g
);
K, z) @. F: M2 I/ K( H5 C" s
' J6 N$ U7 J' D$ B0 I, n7 x/ G; Y, A" v2 U5 z9 `: D
CString translateUPnPResult(HRESULT hr);
G# `; e* m0 E! }! yHRESULT UPnPMessage(HRESULT hr);0 s: _/ q9 B z& n4 ]2 u: L
- z: S z3 R7 U$ K. B W2 ?
2 s7 ?* c' C1 }/ {/ i, B9 W5 A
class CUPnPImplWinServ: public CUPnPImpl* o+ S; b( V! s1 X% y/ \" \' {3 S$ o
{
) M' P Y2 z0 L2 n& b, [ friend class CDeviceFinderCallback;
$ L5 a9 V; ]6 Q; Y, |' ` friend class CServiceCallback;
9 M$ T& _/ E. c$ F# g// Construction* Z+ P+ R# K. j
public:
$ v6 [4 A& {- Z& m virtual ~CUPnPImplWinServ();
8 R" Z& `! a' C2 P' S& H, ? CUPnPImplWinServ();
+ K' L: E5 J/ w4 N. H5 o( \1 R b9 X
8 T7 K t p y% w4 J virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }3 [, N# A! t! Z( f* _: G& v/ }
virtual void StopAsyncFind();
1 L4 o! f6 R% | virtual void DeletePorts();/ J" V# _! J; W$ O* ~& o; H: U
virtual bool IsReady();
6 t) c& U0 ~2 K( G2 D6 i virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
$ U1 j6 ^1 g) C2 f
3 \5 X( @1 f7 [$ h
0 e- ^8 E% q1 V+ |! j+ r# ` // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)+ h# M& T1 D* v
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
' {" h8 [6 W8 p( T( ?( ?( S virtual bool CheckAndRefresh() { return false; };
! [0 E8 |8 d' Y- R; A3 s
2 C" b! k9 r7 Q7 a* ^, {6 P$ c7 s5 f% r
protected:
- ~( [ @6 b7 Y4 G: K void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
6 B* S: {" E( y- y void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);/ P z: j E. e, [8 b8 t
void RemoveDevice(CComBSTR bsUDN);
0 ^- a8 g- i! z$ V: G8 j bool OnSearchComplete();, I8 e1 a$ t& @; f* z* H0 z
void Init();, y, V B9 \7 K5 n5 q* Z
/ p4 T. [6 V% I9 Q. B! u6 B) g: m. r/ ^! k4 s) V
inline bool IsAsyncFindRunning()
4 \- U: `* Y% Q5 s {+ r7 f x( ?' n+ A- z
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )( k* m( b" k; g/ V4 C, F' Y4 p
{5 {1 J( H3 P! Q3 [
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
& Y! o" k; d$ \9 M/ ^ m_bAsyncFindRunning = false;, F5 z: j: ~' g1 D' y
}1 v, s1 n u% Z. S
MSG msg;0 ]4 \' c5 u0 a1 w; V
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
' K, o9 X0 q6 K1 F% [: m6 E& o {- N7 x& m* V1 z' J' ^4 d
TranslateMessage( &msg );1 `$ M% V( j6 [9 d
DispatchMessage( &msg );
9 U: P! {6 Y, e- g% \ }
5 F5 X, h6 w1 u e1 a p6 f return m_bAsyncFindRunning;. |" u& |# B8 \
}
5 J2 s; a! I: R5 o) e$ y
) `. T; {) k; Q1 n C3 s7 J' J! H1 K4 P* w) |
TRISTATE m_bUPnPDeviceConnected;4 C) J9 c- V) v. @/ O% ^" o5 _; m% w
% O9 @6 h2 `( f! K8 Y! {5 D& l) N4 a
) K2 E- w0 s. F3 u D$ ?// Implementation; m$ ]# k2 `% ^
// API functions
) i% T1 Z( E/ D: ]1 l) Q' i# g SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
' {( \9 i3 i8 J* c( i z3 B) e SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);: ^/ Q- L" M# Z' z9 W
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);9 c6 I( x7 F1 r* a1 o6 ]% j
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);( B: U5 t7 u, t( ?
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);. }# r/ S# O1 H, z) @0 E5 s
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);2 J& ]$ o5 F# w. G$ J
: }( P! ^% f& M5 C9 y
3 F& b' W4 j9 z* G5 D r/ l TGetBestInterface m_pfGetBestInterface;
; ?' o' }2 W/ H3 B3 T* |8 ^ TGetIpAddrTable m_pfGetIpAddrTable;
9 c; H& U' R9 d) Z- g TGetIfEntry m_pfGetIfEntry;
5 i, E0 I) \( Z. \+ v
% W5 B; |% n: w" ?2 C& W7 J5 C: X A5 f$ T1 J1 k% w+ Z
static FinderPointer CreateFinderInstance();. H1 w" X p8 S! x8 } i5 O2 l9 u
struct FindDevice : std::unary_function< DevicePointer, bool >' m3 }+ [/ c8 W; ?0 }' g, }: J
{% i) V* T) d6 ?: I$ g% d+ L/ z
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}0 Z2 m' e: C. j* Q8 E+ c
result_type operator()(argument_type device) const5 I: Z+ O+ L+ R" |& N
{& {4 b; ?; k) [, `
CComBSTR deviceName;
7 t0 }2 ^8 m* C7 g3 |! x$ @ HRESULT hr = device->get_UniqueDeviceName( &deviceName );+ M( x3 E# X0 ?( _4 R. ~& }" x
4 o# V. m! u4 m* \! x% `- Q& {+ r8 \+ q
if ( FAILED( hr ) )& t" B! ]6 v# G6 c/ X' e2 v k8 { O* o
return UPnPMessage( hr ), false;7 B2 y5 Z$ Z4 P8 |: w6 N
+ E7 [! U+ d: \' _/ E6 z! S) J0 _) `; B
return wcscmp( deviceName.m_str, m_udn ) == 0;
) q" {( d. K+ A, p; I- M& c, L* Q }
! ]9 b* r: R* k& T" Q, r$ Q CComBSTR m_udn;
7 k* ^1 z# y& _( r7 I5 k9 v1 m9 u# Q# N };) C- u4 |. h* m+ w
. i4 h) D1 A4 I! }) Y# Y8 m8 u1 l; x void ProcessAsyncFind(CComBSTR bsSearchType);
; Y4 L2 T* _* N! |4 z% L3 z3 ^ HRESULT GetDeviceServices(DevicePointer pDevice);
) |; _2 B8 h$ P9 g. V void StartPortMapping();+ G2 K4 H7 l8 _' D% v
HRESULT MapPort(const ServicePointer& service);
- d% u8 x9 D- e2 k' J. [ void DeleteExistingPortMappings(ServicePointer pService);
, C. l( t3 ?, B7 Z7 O void CreatePortMappings(ServicePointer pService);
( O0 w w) ]( d7 ~& @, r& \7 W HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
5 m3 J0 W2 m% C+ U- @5 R$ v! A HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 1 B: h* M, G4 ^- k6 i
LPCTSTR pszInArgString, CString& strResult);
6 ?2 O9 p% e* Y7 U# f void StopUPnPService();
" d1 N1 L8 } [5 E& M7 A& ]" l" {" C- g" k
' s; P. O5 z% H+ m) a" j3 F
// Utility functions; V& d {" x! e1 z# X! L7 r& k
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
9 g% A" b1 g4 d2 B* K; T- [ INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);5 }/ \7 M s* N. s( ~7 k( L/ N1 e
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);, {3 }* @, {( @: `5 ]
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);% l; C/ ~, `9 r* i. K
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
% y$ A7 F2 @ V6 g v# R1 V* L' ^ HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);: m# }; x8 m' ?* k
CString GetLocalRoutableIP(ServicePointer pService);
0 J/ Y$ o# `, f2 L( K# U2 _: k* Z/ I% E: t
. r1 V2 E- o1 j8 N3 s2 v// Private members
/ G8 J! Z7 F8 u" h- C0 Rprivate:
6 j( M$ Y1 y4 h8 d& q+ J/ E+ H DWORD m_tLastEvent; // When the last event was received?
- p2 |- I( |* d& D std::vector< DevicePointer > m_pDevices;
; s4 j5 e3 |* b/ W. f& R std::vector< ServicePointer > m_pServices;
7 W8 m3 y" ^6 ~& e2 b) b FinderPointer m_pDeviceFinder;
$ `5 Y% F& n! V3 q; ~) x- { DeviceFinderCallback m_pDeviceFinderCallback; x: G0 N( n2 p0 q$ ?
ServiceCallback m_pServiceCallback;
6 V& X' ~3 @7 i' o4 l5 L1 W/ o! U4 }' B4 r0 g/ V( o+ D! D
0 T2 Z6 ~, x1 j LONG m_nAsyncFindHandle;
$ o! b. R& c( R* X, j5 ~) k. h+ j bool m_bCOM;
! e: w3 ~; Z, C2 X$ }, n9 q+ o bool m_bPortIsFree;
1 k3 h6 f: ]$ s CString m_sLocalIP;- n8 \/ \; U2 ~5 w) W( G& u# Y6 J
CString m_sExternalIP;
9 u( D$ v" Y8 ]( m$ I4 Q, F4 m bool m_bADSL; // Is the device ADSL?5 x% t6 U- y. U. @7 _2 J
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?0 t0 F; e% j' X0 t7 b! C( _+ ~
bool m_bInited;
Q0 {0 ^+ l4 g5 a bool m_bAsyncFindRunning;. F* b" B1 o9 O) ^5 `
HMODULE m_hADVAPI32_DLL;
# \2 L' |. p3 ~" ^% z% r HMODULE m_hIPHLPAPI_DLL;
' y0 k- ?( x2 |" p8 m bool m_bSecondTry;
; d+ W/ C7 G: U bool m_bServiceStartedByEmule;
4 C5 `5 N0 `; ^7 W6 _ bool m_bDisableWANIPSetup;
( `) _0 s1 o: k6 Z bool m_bDisableWANPPPSetup;$ Q& r% v: N. y- c$ x, ?# D$ A
/ q* u: Y8 T; b/ r q. _+ O! n1 g8 c# @5 M' {" h
};+ [) b& X5 N: T8 a8 J4 J% u
0 _( K/ }% Z+ {) y
' r5 C! g4 ^0 L. j& V
// DeviceFinder Callback4 T+ n& g; p3 K/ u2 B0 u4 ^$ h
class CDeviceFinderCallback# F; Q$ }2 @" K, x: r- V
: public IUPnPDeviceFinderCallback6 l2 M2 R# C6 C, |
{+ B- w$ T* ?- b1 T, o' B: Y/ l( C
public:
; a0 i V% f1 P4 X `& ~ CDeviceFinderCallback(CUPnPImplWinServ& instance)
* m; V; I0 C( { : m_instance( instance )6 ^/ J4 G6 ?( l6 e
{ m_lRefCount = 0; }
# _! D- B r$ ?7 `
/ `2 Q* P8 I6 E- @* {
, ~! x6 d$ W( Q7 L8 \. |$ ]) i STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
$ o- [' G/ t, C# u/ ] STDMETHODIMP_(ULONG) AddRef();
% g* e W u2 l# j- `( d7 ?; _ STDMETHODIMP_(ULONG) Release();
2 ]- J) y8 x' ]# J3 n7 _$ ^
' x: Q( R9 V! y2 _+ d9 W; x2 ?" {: h3 }# d9 `& E. D E
// implementation' S: c/ O: W7 U1 L; l
private:! R! `; P8 U1 R# u
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
6 g2 z/ e: o2 S: k' D6 z, @& P) h9 p HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);& j$ q) A5 l6 {! J/ V
HRESULT __stdcall SearchComplete(LONG nFindData);- ]% _4 o# l- R% z
4 _/ m6 o( b% e- Q
% G8 A+ E! {7 Y8 C1 Z, bprivate: Y7 ~( g$ F$ W( ~+ ]! W/ b
CUPnPImplWinServ& m_instance;
( D; O% O* W) ^& @) D+ m) [* d LONG m_lRefCount;3 m. C+ X6 _; d0 o! Q
}; H! G1 n0 j& L* K, R2 d
5 a0 b6 P/ X/ O: n" G/ }
! h( a) h, T0 W+ y8 p: W// Service Callback ! ] Q, y/ S% c9 [
class CServiceCallback
. D( Z' @ s8 p( ]8 ~( Y* u+ t' Y. c : public IUPnPServiceCallback
, ^( q; y& j9 _8 J{
+ m+ G3 [% c8 ^ j5 ypublic:: F0 C/ Z9 u9 W; S' N
CServiceCallback(CUPnPImplWinServ& instance)
4 q: M# x5 `, O% C5 ` : m_instance( instance )
9 O/ v4 S6 S3 } { m_lRefCount = 0; }
, h' F2 s- ?% Y/ u( ` 1 s( ?7 t6 t* H) F
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);; A. ]8 v8 R: d3 q4 i
STDMETHODIMP_(ULONG) AddRef();7 f1 R+ Y4 q9 k
STDMETHODIMP_(ULONG) Release();. O3 v1 b2 p2 |$ K
) [/ M1 ~* {9 {
) ]; L7 e6 V# |7 e+ D// implementation
" \8 A: v, {; C. x* R4 @9 {private:
' |% _9 v5 B/ @& G1 } HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
( ~+ Q) H/ ^' h6 y6 E HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
0 g7 _- Z- s! @5 C
7 o8 ^3 d0 O6 G! Y8 C1 B4 Q3 _2 l/ o/ d5 Q0 X' o
private:
% ^1 K+ V0 R9 y8 t/ t4 m# { CUPnPImplWinServ& m_instance;5 W( n" ]) ]7 r2 b' s
LONG m_lRefCount;6 ]5 M- L x' E+ A6 N C8 Z) S3 P5 F
};
3 z8 c% p" w0 _7 V9 A' C7 T* a
9 ]& Q+ I+ N( \$ v
- B* v3 A2 E- @+ i# N* o7 u/////////////////////////////////////////////////4 c9 `! I6 v, a6 [
; X% h: C/ v; U! I6 X- j- ?$ o
9 I9 T* Z. A* ~4 v2 _9 f7 v使用时只需要使用抽象类的接口。
4 P" ?1 X+ C! h F$ o$ _CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.% ]: g! b" A! }! A
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
+ a- T' S/ |1 P% n2 _5 X7 k: t1 \CUPnPImpl::StopAsyncFind停止设备查找.. Q( O/ u8 S+ j7 ? `, m
CUPnPImpl::DeletePorts删除端口映射. |
|