|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
+ L$ l, k: }6 |4 M
. a, U; g4 g' w2 Q4 I9 j( |
0 t! h/ U4 ?1 L+ p///////////////////////////////////////////
; y' Y0 `$ m( ~* X! E a+ V/ @//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
' d' X1 L9 G9 G9 q3 j% ?
5 `+ ?# J) z( l8 P
' @1 e) {4 m/ g" ~5 f' u#pragma once
C/ E2 Z2 V' S& n, E#include <exception>
! y7 n0 ?8 k( H% [
# d3 }& S1 R$ c6 d$ o8 ~. k8 a1 O P7 k
enum TRISTATE{
( m; F6 R7 h# k& h TRIS_FALSE,# t9 t: ~3 }6 n
TRIS_UNKNOWN,
7 `4 F9 Z2 [: s6 e8 E/ j TRIS_TRUE
) n2 ~. f7 s4 k# C. g9 z' U}; b8 T3 ^, ^( @. ]3 h
1 R3 S& G" g8 q% _: s; F( G, A
F0 Z0 Z- O2 Q w8 J3 Eenum UPNP_IMPLEMENTATION{
5 q8 p2 {9 z [) A2 a* L& |! R5 b UPNP_IMPL_WINDOWSERVICE = 0,
+ e4 Y% C# B" } UPNP_IMPL_MINIUPNPLIB,
, x& [, c1 N6 ^ UPNP_IMPL_NONE /*last*/ n/ g: j* o9 X9 W% L
};1 V7 D; n, ]4 N0 ~+ Y: h9 a
+ n) G: P/ k7 U
( k! P6 B# R3 J: K0 R3 B; J1 ]: {# {& v3 ?/ ?
& F7 S' K% ~( h5 U% N4 J9 V
class CUPnPImpl
4 v5 M" U5 y3 P8 h2 n{
$ Q6 e& z) r2 N, r- ~7 epublic:- K+ B; M) {2 c" h
CUPnPImpl();
+ N# V9 h; ]- V' _/ b virtual ~CUPnPImpl();: c1 W, F( v8 ?- Z
struct UPnPError : std::exception {};4 M% X! v _! M# i8 K
enum {
7 B* f' K" N( B% C" F, Q6 z UPNP_OK,
+ x. h. R3 D1 F7 J4 N5 |' _ UPNP_FAILED,0 e( N& G+ ?0 s* y
UPNP_TIMEOUT! l1 `1 H4 A) Q, ^. ^$ k, j2 {+ p, E
};* Q9 x1 m# S. I
7 o; ^; [4 |' n* g# |6 g4 z5 w% I' f X/ Z2 H
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
5 h: h, I% I3 Z1 r3 H p' ~6 e virtual bool CheckAndRefresh() = 0;0 S4 T5 }1 r& F1 k( u$ p" G8 U3 b% d
virtual void StopAsyncFind() = 0;
3 Z$ _6 s: n: A0 e- ~ virtual void DeletePorts() = 0;
5 W- V) K Y6 O2 _# n) m7 x' P virtual bool IsReady() = 0;
$ v' ]7 y' b: I; u' g, X) a virtual int GetImplementationID() = 0;. ^. n" Z1 Q% X4 f( ~3 ~6 z, s# F8 [5 j
* ~- M$ P4 C: M3 J
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping8 y$ C, o5 X; L& Y0 t- [
& Z6 J4 W) N Y+ ?% m& G- a1 V$ I
* ^7 g8 T/ j6 a8 p
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
8 b( h3 B& z/ m TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }2 ]0 U6 ^/ `/ U# V2 w6 I$ [
uint16 GetUsedTCPPort() { return m_nTCPPort; }
- f& u! M: V& X1 M# b" W uint16 GetUsedUDPPort() { return m_nUDPPort; }
8 A5 c& x3 Q) B$ ?2 }# P3 {- i& r5 k ^2 A! X4 O1 ?
* B3 s5 l# m* }' q4 V8 c6 ^3 r
// Implementation
% O$ p+ F( \- H6 `* }5 uprotected:% r' G" b7 P+ s! @
volatile TRISTATE m_bUPnPPortsForwarded;6 [4 V1 l0 m# B5 B+ K3 P/ K
void SendResultMessage();5 Q" D% q0 x! ?
uint16 m_nUDPPort;
& Y, }# {9 K8 w5 K9 z5 w N uint16 m_nTCPPort;5 ?" R. {9 k8 X3 x- b
uint16 m_nTCPWebPort;) |* a V6 m: i6 B
bool m_bCheckAndRefresh;
7 O U" H2 {3 Y6 o: @" K2 ^+ K8 {/ o6 z5 C7 O9 i
& O8 V! z6 a H! D' k+ s6 zprivate: y5 [3 b6 Q# ~( {
HWND m_hResultMessageWindow;
" w" _" V9 Z9 T7 G2 H+ _ UINT m_nResultMessageID;
% J# V* ?" X# n! X) k P7 s* u- N$ J6 _3 c& i/ U; z
3 a" c2 s& g c! H! ?9 M};2 a2 u! c2 E$ h# `1 a
& U: M5 O/ k# { ?4 a) y. ~: R4 k T( Y6 L V3 ~( h
// Dummy Implementation to be used when no other implementation is available
$ l* H$ ~ F' N8 {5 ~0 Aclass CUPnPImplNone: public CUPnPImpl, B6 p6 u, k2 a4 k0 V
{
0 T& J3 e3 v0 v- c" u, lpublic:7 x: V5 v" t( r5 b& u/ I
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }4 D2 G k' z a: @5 k
virtual bool CheckAndRefresh() { return false; }" x9 a* M; T. Z" u3 J# W
virtual void StopAsyncFind() { }
; H# n- O! ?1 {5 Y) C virtual void DeletePorts() { }
$ @: t9 K8 X3 ] virtual bool IsReady() { return false; }. c* h" \# T, P: w7 F, h
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
7 {" ~& h' f) }! q6 P( o! u};' l5 h* l+ p6 l4 C6 D [9 K/ Y
0 Y6 [# j5 z0 J9 u: f1 s
9 n$ E {# K+ l& ~# V8 d" l$ h! R/////////////////////////////////////% P" Y" Y1 U. @% l! D/ O. ?
//下面是使用windows操作系统自带的UPNP功能的子类
3 o8 I( u$ g9 Q1 s1 z9 r: \
0 Q( d& C7 g& M7 C$ R0 k
( `& l0 G0 o; J8 o B Z#pragma once
# _. t8 c& L! ]. a#pragma warning( disable: 4355 )
* ~+ m) Q" r+ k0 P: x
& |) \8 G+ ^* |0 J9 O5 e* R( b2 Z% K! ~7 `$ b, M% P! i, c ?- h
#include "UPnPImpl.h"
( |8 f; { E# y( C! l7 h9 T2 n' Q#include <upnp.h>: {: @2 U- {* @8 G( M
#include <iphlpapi.h>
* o: O, ? O% e7 y, B5 q/ v9 W3 U#include <comdef.h>
6 y" V$ s$ D8 ?. J- F4 o8 e#include <winsvc.h>$ n: Q3 w3 S0 h0 N% z% q% T
, U0 a2 a) W l% y% y! Z: `+ i# j$ \
& z D. g) q9 i
#include <vector>
* V5 O% \3 _. ^5 D$ w#include <exception>7 |4 Z4 G* ^6 ?
#include <functional>* {3 J) e2 g% [: y" c2 M( y. e
. S6 T& ]2 Q9 [% | H4 |2 E
% ^. d1 ^) q, _3 W% N* z
3 Z0 I1 F( E( W9 J
6 c2 p' ]! [) {1 n* a
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;1 q' j% N; ^ c X: h+ g
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
- t# o: C: y) Q2 X" _9 @- l5 Ptypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
- M, t8 u, s; M& `9 g9 Wtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;" H6 C% o7 f* J7 o6 ~
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;0 S6 x( w3 A. }
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;: z) U5 R2 U( e! `1 m) O% a$ p
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
6 T& I5 ?) _0 u6 c$ Y$ m" Y& n& G0 m# w$ c _( k% \
4 {4 Z2 U4 f# m9 J3 W7 D6 W% I) Otypedef DWORD (WINAPI* TGetBestInterface) (
/ _' [- ^1 d+ M! t* X: c+ \7 h IPAddr dwDestAddr,/ Z" A0 }+ k& N) [/ F, K+ S1 u h
PDWORD pdwBestIfIndex# ?# N7 s' S0 |' w" z
);: S1 W# K7 H8 q# e# C3 Z e
' s3 R0 y/ I9 n5 a2 L4 `7 i
" L/ E c& e- I- h: s7 btypedef DWORD (WINAPI* TGetIpAddrTable) (
) g! J) F8 e( X2 _5 c" Q) h) O7 S PMIB_IPADDRTABLE pIpAddrTable,: }' f8 O; M, E
PULONG pdwSize,+ G: d+ K( i+ ~% n4 R/ @
BOOL bOrder
' o+ `$ Q. }8 V9 Q) _7 U, f' ~);
! F8 L& J5 U4 m4 Q. b7 ^3 O( u( B9 L, Z: `/ I% q
! C3 v- f" D) w% c3 Utypedef DWORD (WINAPI* TGetIfEntry) (! h* `0 @+ |; Q" ~: N2 {
PMIB_IFROW pIfRow* K" S% V, Y: U! Q6 `
);
8 c- A6 C9 v+ t1 V* J* E* |9 d; ?; a+ `- H" B
, m' R5 B; p* c t' O3 @" Z
CString translateUPnPResult(HRESULT hr);/ K9 Y4 I3 M" Y# p( ^
HRESULT UPnPMessage(HRESULT hr); s. R# N& X9 h3 C5 g0 p$ n
! \0 @* }, K3 p8 e: d; O( p$ ]9 x4 [& T) d; ?2 ^
class CUPnPImplWinServ: public CUPnPImpl
8 \$ N: u8 z4 ?# `: N0 E{) \' g8 N0 i, V% s# I9 @+ I
friend class CDeviceFinderCallback;
; I- H' U3 K+ J( T5 [; x friend class CServiceCallback;
/ k, U5 G) B' Y; x) O. D! L// Construction
& O" S: c% T0 }1 I( V/ ]8 i, G+ hpublic:
, G. G7 [* d1 [ `. a virtual ~CUPnPImplWinServ();! U. Z8 A+ V6 ~4 S h6 r
CUPnPImplWinServ();
. Z6 W2 a2 J, l$ S9 R& ?7 i: M$ V5 a1 Y/ j5 O; E. I0 w
& i5 I5 k' Y( w virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
' i" O: A6 }2 S& _3 l5 j: c+ ~4 } virtual void StopAsyncFind();
" G% j# r1 o z1 m9 d virtual void DeletePorts();
# }% r; p- Y0 B1 S7 g/ h) R: A virtual bool IsReady(); L; B) p4 x: s4 n. H
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
. v, F0 ~2 e4 C, C4 ~& V
! V8 r* X4 m& R) ~$ P0 i+ V( ~
9 b% N& o- \" S# u( P // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
* }5 }/ f6 y2 v( { j; @ // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
B" x, D t# e9 |4 X( l* q virtual bool CheckAndRefresh() { return false; };
6 h+ C* c$ Y) [2 Q, l1 c( u7 d) u1 [# \
$ k& L7 S) c! d* j/ F4 F7 E
protected:" Y5 J. o8 c: S* A; v
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);0 D) ` z5 S* E! z2 b0 P3 T
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
& z" E" Y/ y4 m void RemoveDevice(CComBSTR bsUDN);8 o' r) p+ V+ N
bool OnSearchComplete();. T9 A- `$ A" w& z+ r+ r
void Init();; Y5 d+ z' S. \0 ^
, d# L3 I0 _2 Q4 h7 i2 |' l$ p. n$ ]/ f" j$ i( a, E4 g
inline bool IsAsyncFindRunning() , S: J# h+ t% e& _* ~& U
{
x/ y6 @' [$ a5 r" z: L& K( P if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ), C& T# I9 q$ A- w0 O+ O' j+ v. h
{
! r3 M3 B+ ~3 O! [ m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );# I3 F0 q! E9 ?& ?* n9 y( B4 a, f
m_bAsyncFindRunning = false;1 |3 ~2 j0 A1 T) z
}
* B# N/ a% P) l4 T; ? MSG msg;
+ D" q" G) o5 J5 g! R while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
! {3 n1 M! N: H" B: ? {
7 K. \, L4 G& g5 |7 i/ H' H4 Z, ~ TranslateMessage( &msg );
$ I2 j7 R. w8 c- h6 ]" C0 Q DispatchMessage( &msg );, ^+ V- I& n2 x# B' M& j9 T
}, c+ p, V& `9 w) c
return m_bAsyncFindRunning;
7 S1 v& q2 t. y }
# k8 Q% j9 ^0 b. ? `( j
( N7 {/ {; u$ a4 [2 ?5 q
* f7 _- u, Q- [& W* `/ L TRISTATE m_bUPnPDeviceConnected;' b) @7 ]+ L- J# i
A* M J$ q4 S. {
( ~ Y; X1 L: p/ E; o4 n// Implementation
6 d+ E" j4 z8 J1 \ // API functions
( ^0 u* ?+ k `4 i; L. p% i" ?% E5 ^ SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
5 i; a* r* w/ i/ w/ Z1 `( _1 K1 j SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
2 j# f: \" k; T! P1 b BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);$ B0 q; P( P* l5 s2 e
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
' A- L c7 Q; ?3 u3 ]7 r BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);# O% G6 F- z3 Q4 |
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);1 ~' ]5 _$ v* R1 S; E: Q+ a" R
0 t: H9 O# k4 I5 p$ g4 P+ K6 p; ^7 \1 F- o$ r& T4 o3 E7 T
TGetBestInterface m_pfGetBestInterface;) }* [2 N, H1 w; r. W; u
TGetIpAddrTable m_pfGetIpAddrTable;
$ q( n4 v" o9 m+ U$ { TGetIfEntry m_pfGetIfEntry;5 U1 F2 T% u" ]9 M% d/ z/ \
9 ^: Q) Y# c6 ?1 t+ |! \) r, C5 M2 Y ~' S3 F% \# E! ~
static FinderPointer CreateFinderInstance();
( D4 P" _$ r, H O9 u' j struct FindDevice : std::unary_function< DevicePointer, bool >/ u8 r, d$ E I# d J
{0 m. n) U8 \9 {% j& u- [3 Y
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
6 ]/ c9 A& U. E# l+ e result_type operator()(argument_type device) const8 G* a$ q9 |! e0 T/ s9 p
{
( e, _4 A' z6 z+ P T! p/ L CComBSTR deviceName;1 {% l: q1 t7 ^6 E$ N
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
( Q9 o$ u/ s) a, q/ W! j$ e! E% f+ Q! M
# m) e0 R, E0 [* v$ m7 m, P/ \
if ( FAILED( hr ) )
* Z8 C P+ L8 D; }+ E0 ~1 x return UPnPMessage( hr ), false;. h5 h9 `" F. g! j
6 S4 V$ V% ~+ {9 K# \* f, ?7 x+ U3 ]1 y
return wcscmp( deviceName.m_str, m_udn ) == 0;
+ D! w! c1 _4 R8 q* C } Y) E$ [- p/ _0 h8 e( Z
CComBSTR m_udn;+ G1 O- o# o% W4 o8 R' J2 z
};5 ^" N V* E6 @, E& B$ y
% P1 T4 Q b9 h4 ~" ?
void ProcessAsyncFind(CComBSTR bsSearchType);
% Y* M/ h2 E( b$ `* V3 ~ HRESULT GetDeviceServices(DevicePointer pDevice);# C4 a- S5 S% [/ v4 J. t7 [# w
void StartPortMapping();
- G7 w2 _3 p. x' m/ E5 R HRESULT MapPort(const ServicePointer& service);+ {% H c H$ T% T/ \) v
void DeleteExistingPortMappings(ServicePointer pService);
7 X% U: |- h/ A: a+ {) L void CreatePortMappings(ServicePointer pService);1 c! h& ~+ |, ~% P
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
u/ U* B* ?' k. ?* L) v7 z HRESULT InvokeAction(ServicePointer pService, CComBSTR action, $ e0 D% P1 i1 F
LPCTSTR pszInArgString, CString& strResult);- ?5 U# v: f$ v' I; q* ?
void StopUPnPService();
0 k7 T0 B$ |, G4 r
7 m# |/ M# b8 b. ^3 w" R0 q
6 V8 s0 @! Q2 [" |2 X# a // Utility functions! X4 `9 A c/ ~6 o9 J2 t# R
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
`. f, A& w3 L0 q9 M INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
/ P d* j3 N% \$ `# [! F INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
+ D* x" ]8 _/ ?# C3 U void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);- K* n6 [, l2 s4 I$ I
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
_! V6 K/ J U HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
: {. O- m' P' L+ J$ B% b CString GetLocalRoutableIP(ServicePointer pService);# E/ f; @; E% g8 g% @! x. b4 @
- }! t* {% E' y% g+ P1 V, g( h% h* ~0 [0 z
// Private members* e8 F( Z# f, \/ C
private: ]6 l3 R! l% a
DWORD m_tLastEvent; // When the last event was received?! E( L- ^0 _! ^( t- J8 w
std::vector< DevicePointer > m_pDevices;
f' q2 ]# ~; N$ v- g std::vector< ServicePointer > m_pServices;
. j w w Y4 z0 n% y FinderPointer m_pDeviceFinder;
$ |( D) c' n/ u DeviceFinderCallback m_pDeviceFinderCallback;
' f. C! ~# g0 ~: |8 ]4 U0 F, v ServiceCallback m_pServiceCallback;6 N' v8 G$ S2 r1 n: M
: B4 q% W4 Y6 K3 T+ w) ]5 n q
O! U. E0 W' c4 d. I$ V1 i- V: g( g LONG m_nAsyncFindHandle;
/ J# O1 J: r7 w/ {1 @ bool m_bCOM;
# {# ?1 @+ Q4 C, V7 [3 ?2 Y) h bool m_bPortIsFree;7 W) h l# i" x! ]) e# y2 k
CString m_sLocalIP;
; ~' I+ \4 V0 X CString m_sExternalIP;8 M2 R% W1 ^4 B6 m
bool m_bADSL; // Is the device ADSL?* [% r% Z" A/ ~, o z5 S$ i0 Q& Q* P
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
+ V3 j( z) F. h( L& [ bool m_bInited;
; {( g5 A5 U& i( E# \- c7 j bool m_bAsyncFindRunning;
, }5 Z3 ]! Q1 P1 ^ b HMODULE m_hADVAPI32_DLL;
) R2 q8 T3 F4 L& v( @$ ]" f HMODULE m_hIPHLPAPI_DLL;
( _7 n7 e9 I+ \5 n& y: {* z/ f1 t C bool m_bSecondTry;3 r Z( H# |% o) C/ G8 l9 ?
bool m_bServiceStartedByEmule;
4 x4 ~+ L8 i! H# ` bool m_bDisableWANIPSetup;- [/ W2 G9 D2 s$ |
bool m_bDisableWANPPPSetup;
5 ]1 A D' D$ a4 @1 ?
2 U. u) X% K; H, s% O% J X$ z
- I7 S- z" f, t8 l5 m- w* I" a" P$ k};
% q6 z2 Z l/ d9 B1 x
* ^( T! w+ I, \3 h1 D5 [, C3 w h6 K/ |
! B) x: N/ l! g) a// DeviceFinder Callback) \# G% r b# {; |4 }2 J0 q4 o
class CDeviceFinderCallback! i" I7 k1 j$ l: O! @
: public IUPnPDeviceFinderCallback! |, K8 @9 J1 @8 D0 d
{
5 k4 |9 t7 @1 A& h9 Xpublic:4 q* y6 V0 @# k8 r
CDeviceFinderCallback(CUPnPImplWinServ& instance). I$ G& k" I M/ M. D5 c
: m_instance( instance )4 z- F; N" \# B! c
{ m_lRefCount = 0; }; p( S( c; k4 u' J; L4 P) j
( m B0 F5 j/ R6 r! J
, h! G9 c% l( t0 b STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
& c# I4 J4 l! W! ]: B STDMETHODIMP_(ULONG) AddRef();
* T2 L- P0 M# n& Q" s STDMETHODIMP_(ULONG) Release();
$ g) B. t2 L Z8 n, X$ _, l: S; M5 d' I W) _5 L/ O+ f1 l! c
; P3 r/ i, G; f" o) w5 ]2 A3 Y5 C1 q
// implementation4 g0 E* r& ~& t: u
private:
/ N( I' U5 u. H$ h8 Q% D HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
& k- }; N2 m! n0 w& \$ H HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
' F7 d# h4 [8 Q% X4 [ HRESULT __stdcall SearchComplete(LONG nFindData);
# M8 g* E) i5 I
. ~6 X a+ x9 b3 \* P1 j( N( f. n, y* m; {1 z! T
private:
7 R! q( Y. T C0 u/ |9 w; i CUPnPImplWinServ& m_instance;
3 R5 [2 c+ J, [$ v, x1 b LONG m_lRefCount;9 d& q8 V: T' h7 n- J$ g
};
. y' H6 L, ?) \$ E: U6 j$ W, w) [8 E! L! F( F, C- ` n
2 l6 p4 b6 V) ~0 r. T c5 Q// Service Callback 9 q- H" s# Q7 X: ?* o' h; P
class CServiceCallback
8 v4 S8 U+ Z# W3 G" o" F/ T : public IUPnPServiceCallback
7 w% Z6 t/ j |7 y6 ?/ i. \{
0 f7 l! v+ w* z6 `7 B+ c7 z3 Tpublic:
1 E* x+ s ?: a% K: O: a CServiceCallback(CUPnPImplWinServ& instance)4 V+ T* N: G* T
: m_instance( instance )
+ h u3 ]" R7 M# _ { m_lRefCount = 0; }0 Q9 [+ @2 p3 j* f8 n9 Q. V, d
& u$ \9 Q, ^' A0 k% E9 Z; P" m3 l O
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);5 Q6 F4 c5 w6 S8 Q% O9 t
STDMETHODIMP_(ULONG) AddRef();
4 G- |" W3 B( y+ S& R s, C- }) @ STDMETHODIMP_(ULONG) Release();% j1 L) c1 q8 U: C! i4 e
- @9 ^; H: ]/ O' m& g7 ` K: H) [5 ? L3 F
// implementation
! V* T( {1 u3 Z& H$ D+ [9 Eprivate:3 M* p% M2 |, U- y
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
2 ?* T- h/ Y+ W HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);+ w! J o+ w" o" N
4 K# h4 B: d! J* J$ S
6 Y& P7 j* Y0 N6 k; hprivate:
( Y' }+ x3 N) C& h CUPnPImplWinServ& m_instance;
9 d0 ?) v z. p6 e+ [5 L4 \ LONG m_lRefCount;
0 U4 [& R+ c. U( G6 @};
6 Q: T# R e( a3 I# \* ~. r {# R, D7 {; }% @, T8 L% _( m
( ~3 a: N8 i E9 @* m/ J& h
/////////////////////////////////////////////////
" q. k( t! y D# v/ Y9 h" n+ U& `% P0 Y; s
/ P1 g% Y' `3 G; Z. [$ z+ I/ \使用时只需要使用抽象类的接口。7 S0 b. \1 x) j( X, }3 \8 a2 r; v
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
. t; l8 h" M, |6 C: A; \' NCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
% m9 u. k; v! n/ H1 T, S9 {CUPnPImpl::StopAsyncFind停止设备查找.! Z P7 X+ [: u7 t1 @1 f
CUPnPImpl::DeletePorts删除端口映射. |
|