|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,3 ?! J# p, [; R$ H4 ]7 r
1 C( v' ^$ O5 b8 {1 h
" s [3 A* M. v///////////////////////////////////////////
5 m4 ?2 n2 P9 H8 R2 H5 K//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
) F+ i8 C: z$ g; M, b- l L+ P. x* ?3 n0 Q, f
, }* h4 J! Z1 V* M7 N1 b, v' @
#pragma once% a1 o3 F9 i+ V5 P! s: ]& ^3 P* i
#include <exception>
2 j. S7 @+ \: [3 s! n2 @* n; J* d1 V4 ]
# r( B) a; I4 i6 x: ]# C enum TRISTATE{: `5 d! ]+ I) X- M- _% k, Q4 h
TRIS_FALSE,% I7 ^; ] r# T' Y
TRIS_UNKNOWN,
: T( O! J- F( Y( r- R1 c! X TRIS_TRUE+ S) W5 Q0 g* k. s% E8 y* F* o, J: l
};
# {; m" M/ H2 `% Q
7 j$ u. Q( y- @4 o+ m* g+ T% i: Z5 h4 @; F. P
enum UPNP_IMPLEMENTATION{! C( S) G l5 a
UPNP_IMPL_WINDOWSERVICE = 0,% t, D+ T7 ?- Q. h* `1 i( Y
UPNP_IMPL_MINIUPNPLIB,
$ D! P1 ?! E3 c% `$ T UPNP_IMPL_NONE /*last*/
' Y7 P6 Z e) ^# n};( V& R6 Q2 e1 U6 F+ e
6 X* d4 J3 ?8 W" y+ \+ `) S- E- W% D7 t( V% f
) v; c& \. l2 k* A8 c
2 ]( N: v* M& j; D9 `# P' ~
class CUPnPImpl2 ~, [; D' ^ J# c% f0 d* o- t+ ~0 S
{2 H0 p1 P) C+ K. O, o) p
public:
/ C: D/ q" s H CUPnPImpl();
0 z" p4 n# C+ v$ N( b! [, e- p virtual ~CUPnPImpl();9 t2 z- L* @( \; `: l9 h, r
struct UPnPError : std::exception {};
# U2 |, Z F1 T4 [' K; D enum {
2 r7 q, X$ X6 Z2 G% u; R8 { UPNP_OK,# Y. e% `: n, @. r# T
UPNP_FAILED,
! L( Y* P" l, k1 j UPNP_TIMEOUT
8 Z, g- f F. H2 O! } };
6 \+ W) w6 m0 W: M6 T" t8 @, u& S3 H; {. x6 R
9 c0 k) k. L+ |: N/ @6 a' m, A" J virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
! P" L7 r7 |- _ virtual bool CheckAndRefresh() = 0;) H, @# N% s R' f- z8 d$ v
virtual void StopAsyncFind() = 0;
( `( ] L" V" H0 S& O1 W2 e# C2 u$ m virtual void DeletePorts() = 0;9 m0 {# m. L9 H3 z4 M; j1 Y
virtual bool IsReady() = 0;
3 W6 i8 w6 m. R- E0 P5 K virtual int GetImplementationID() = 0; b6 ~, E9 X5 ^! J- P/ f6 _6 S
- Q0 ^3 Q+ a2 }. w
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
% J1 k' E. _2 v3 t5 p! r- J5 Z4 l6 v/ ^) z" p
' N @$ Z9 r ? void SetMessageOnResult(HWND hWindow, UINT nMessageID);+ P( X4 ]- {; z/ [: w) Z/ h6 ^/ U
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
- q# L% r* V+ [6 X+ h uint16 GetUsedTCPPort() { return m_nTCPPort; } H8 H8 H/ d4 r4 l& N0 _4 Q
uint16 GetUsedUDPPort() { return m_nUDPPort; }
( C6 u. T. _. g" c1 A# q) Q; {
0 {6 F, M+ z$ j7 W
4 H' \$ P: V. B// Implementation
2 Y( i4 Z: z/ }7 bprotected:
* \9 S& g! W8 Q/ ^ volatile TRISTATE m_bUPnPPortsForwarded;2 C. M, k9 O8 n
void SendResultMessage();+ x \* x9 G8 ^- [: p( _7 h
uint16 m_nUDPPort;3 D- k7 g+ \4 n* i0 a4 ^: }8 f! V
uint16 m_nTCPPort;% x' S" q1 a7 o- u
uint16 m_nTCPWebPort;
2 j" `# T; V% w6 J, F5 x bool m_bCheckAndRefresh;
/ H! l& O( ~2 A6 J6 X3 W
# ^# i9 I8 y8 ]2 o- X% s! l; D
0 O& L2 O4 X' Z: Y6 X3 ~private:
; a+ ]; u0 z1 ~! r* V0 g7 x/ X HWND m_hResultMessageWindow;
' c& e; o4 ]3 g# v+ s UINT m_nResultMessageID;
) C5 ~. E1 g, m7 g9 O3 p( d# v: x3 l/ t' ]
. O9 N* T6 w3 X5 Q: A: J1 X
};; ^! |1 I6 h3 r- x
7 e- w+ H5 T# @. H7 \: V9 Q0 F* t' k! O
// Dummy Implementation to be used when no other implementation is available
* n( X# r6 B" {class CUPnPImplNone: public CUPnPImpl
$ E% H/ n6 w" T- _{
; V- u: h5 }. X6 }; [8 Dpublic:
$ n( q* |5 Z: @4 ^2 f virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
1 p5 J3 ]+ F2 J# h7 j virtual bool CheckAndRefresh() { return false; }
4 g! ~4 S1 u6 p% c# b. j6 ` virtual void StopAsyncFind() { }
( p6 L% ]8 \+ b o virtual void DeletePorts() { }
$ Q0 D2 O$ x7 p' M virtual bool IsReady() { return false; }5 x) p% n2 H; u9 J: i
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }4 ~0 ^8 \. v/ R8 \& U# j
};0 c8 \7 c: |. v1 L. `
2 r2 J1 a6 w5 m1 n1 d6 _7 k; o
5 N o, k0 S# {: ]. g( c2 y/////////////////////////////////////
1 B7 P$ Y2 G b( v# A. ~( p7 K- Y! u//下面是使用windows操作系统自带的UPNP功能的子类
* G" ^# M( j9 Z7 o2 b- b: \3 `# S( e1 S6 h- ?; z
$ m o) R( O. ?/ I2 `8 E( D#pragma once3 H: ?- z% M$ B; r7 D1 ?0 q. W7 Z
#pragma warning( disable: 4355 )4 T4 s# M6 v, l6 y
: {/ K% y9 G; D5 q1 t6 \
6 t4 [$ M) H# w3 T/ H
#include "UPnPImpl.h"
7 D( s1 N: P3 m" { c( R, U5 L#include <upnp.h>- O. ` v6 {1 {% h# K
#include <iphlpapi.h>
% A& ~4 q1 I& L9 t8 v#include <comdef.h>
& B: s. e* N: y8 J% w#include <winsvc.h>
' e( Y5 K/ f! o9 A6 t4 q: `6 W4 h4 Z9 \4 G+ Y
# ?' [* D6 j& L2 x* R4 Q6 N" W#include <vector>
4 S9 l5 t1 L0 p/ V& P#include <exception>5 u; |7 K4 {, Q# e& e0 h) S% H
#include <functional>
" [; I: l6 ?( h/ p* c7 E5 N" Y" V5 g7 ?$ K1 u9 j/ {
9 X! k9 B }# {5 z8 J- B. ]3 c* l
2 { Z. F- q: o9 B3 {
* s4 ?8 V4 k s ~3 w
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;& R$ G7 H. N# Z0 J& c
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
" \$ U% I; x4 r$ ttypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;( Y4 W8 c$ b* W! x, [& _1 @' T
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;0 ]" B6 P, `: x( T* O6 R
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;& C! W H7 W! }7 z! o
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
~# {* l4 p Qtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;3 K9 l7 h+ d/ o7 M. H1 h, s
- S# }! {. U% p, }% n
) ?& Y, u4 L$ S6 O% Ttypedef DWORD (WINAPI* TGetBestInterface) (
9 ~1 u9 z" j5 f" \6 H/ c IPAddr dwDestAddr,7 P$ E9 n( ^" C( p' E7 B
PDWORD pdwBestIfIndex. ~6 o" n; \5 d8 H& w
);
6 w8 R' W) H* Z2 g, \2 N: l) A
2 m% ?5 {: ?6 m. [7 P' @) E" ^$ T8 H0 Q# m, s3 F
typedef DWORD (WINAPI* TGetIpAddrTable) (
2 V7 V" h' h; H" P0 Q0 j { PMIB_IPADDRTABLE pIpAddrTable,1 T+ V r6 g4 H5 d- G$ V& j
PULONG pdwSize,4 ^7 ?/ [7 B1 L+ u+ _
BOOL bOrder
& L# W: n7 G& ]+ v);. g8 k- q2 Y! Z6 M$ g
* u" X* D, ]5 @6 m
4 v$ W: E2 r6 R" w. r# Z: n* A1 Ntypedef DWORD (WINAPI* TGetIfEntry) (
4 d% m; j3 _0 L$ a3 v7 n PMIB_IFROW pIfRow
! M3 r# p/ V7 F9 O: h b);
, b5 [ O$ {/ S) K Z* b1 k* ]2 T8 w0 Z
% ^' u; j3 |% V$ lCString translateUPnPResult(HRESULT hr);% v6 G# i# T5 Z1 i# p0 b: f
HRESULT UPnPMessage(HRESULT hr);
9 i1 z$ E0 V: W1 T4 k$ c/ b+ D
# o, _' F# n: X2 E
$ U0 n1 g' c9 f, s8 w) S4 B2 vclass CUPnPImplWinServ: public CUPnPImpl5 e" [7 r. |8 P$ H; p
{; p8 u: }6 c/ O' `& B
friend class CDeviceFinderCallback;
/ u( [- Y' x" ]% s0 Q4 L friend class CServiceCallback;
, Z" J* [6 {4 \( H// Construction
% j# q0 F* ~# G/ b- L1 q. ~public:" h \0 r" d) j/ i1 l
virtual ~CUPnPImplWinServ();
- u6 C) E& X5 N( @4 n c4 [: R CUPnPImplWinServ();
5 T. ~- }1 z) I6 A! L1 s
. b1 h" n3 |6 |% L# B1 e$ K2 L# w5 D( m& J9 L, |
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }4 b: C9 b. {0 f4 ^# r" q4 w1 b" s
virtual void StopAsyncFind();6 Y" ^( j9 E6 e' v2 o5 @1 {2 j
virtual void DeletePorts();9 _- q. N: [0 z2 s# `% I
virtual bool IsReady();/ h/ c' u* u' i1 q+ ], F# a
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
3 |6 o) j+ }/ A, Q- W
" Y) n( r! C1 ^( b8 Z/ g& i2 M3 t1 ?' V/ f
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)" `4 O' y0 ]9 e2 E3 |3 f8 S* t% ]
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
. @) ~( {% a% A9 S2 O0 ^9 h4 K6 K virtual bool CheckAndRefresh() { return false; };1 y; ` U1 L, g- y' [" |
i% [# z. w0 N( f# |! s/ _, o
" |9 q- Z5 J% H2 \; ~* Yprotected:
: b3 o$ a* @, U3 {0 ~1 _+ M1 U void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);: f. v( F2 s' J9 M1 h1 m) n4 S
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0); K" s/ X8 A4 [0 Q1 u7 O
void RemoveDevice(CComBSTR bsUDN);; D! S& [# f$ }4 P' ^4 D* i) B2 F
bool OnSearchComplete();5 ]( ?$ e# K( X& D1 v! B4 X
void Init();" S& D4 h: o# [$ J# D- g4 R
9 N; J# J) q7 S% U' i. Y' f
. Z2 H: x3 T% x R" s9 i
inline bool IsAsyncFindRunning()
' n( k* g+ e1 A# Y {
) M) S& q& s! u# E ? if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )7 ~, D# [4 W3 Y3 E" U
{/ O0 @% T5 t( b
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
% c* x" E2 B' q) b" I4 x m_bAsyncFindRunning = false;
$ o$ \# M" Q& @9 h }' B( u) I7 F! g% W% S
MSG msg;* L1 y: B/ Q- j1 Y7 v) }5 @
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
1 Z/ }- L' C$ M. J* g% r {3 \/ y$ {* L3 C
TranslateMessage( &msg );& x1 [ {# V* Z3 R/ l3 S$ r( L2 q! [
DispatchMessage( &msg );5 ^: v1 n' T8 N( r/ S1 O5 J
}2 e9 Q" Y+ y7 l# w
return m_bAsyncFindRunning;
0 o, ~9 z. _$ u V. b! f }) Q/ `' `, o1 ]
2 ~* _* e. i! Z
2 _7 k$ X/ u# W6 q+ A8 s" k
TRISTATE m_bUPnPDeviceConnected;
: S+ z6 h7 Q; c9 v( e
6 m/ c8 C3 o4 ^$ U6 E' `* t/ [" E& _. n$ v
// Implementation. v1 ?7 E$ R* h% @" H! G8 o7 [
// API functions6 H4 t' W; y# d7 O9 [% A7 p e
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
2 O2 ~# d' m$ m; [- h6 n/ t SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
) o+ J$ a {# t9 t6 q BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
9 C7 u& ?% [4 }* P, S: \: I BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);7 q; i9 o% X% Y
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
( a; k$ |" D! L$ {3 _ BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
6 h* b6 [: _% x$ |. S8 ~( o; y% f& R' R
! Q3 n: e- f& m) y' g% D TGetBestInterface m_pfGetBestInterface;) J& u" ]. J' C. h
TGetIpAddrTable m_pfGetIpAddrTable;4 t- o9 Z8 t: q( D' O' f' ?) f! U7 j
TGetIfEntry m_pfGetIfEntry;: w! }) p0 _5 f( e2 I5 b
( O. u4 U+ S3 r8 Z8 Q, T4 Q& U; d# n5 ]( F' V
static FinderPointer CreateFinderInstance();% V: R" f! |8 t' m* |& g" I
struct FindDevice : std::unary_function< DevicePointer, bool >' u! Q) L2 h6 x" k5 T6 h4 ]0 n
{
& X2 f4 h5 X+ _7 T2 } FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
( s5 I; X6 T# @& V1 N J+ L result_type operator()(argument_type device) const; e; t7 O; u* _1 k8 C# h
{) O5 O+ h3 l% L/ T. N# E6 x
CComBSTR deviceName;5 B% |% E: z0 M, u6 K2 S
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
+ [; c" O+ m1 z" Y R1 m" I% E# F6 M6 @ k0 L0 e: s7 d
0 K( V% @& ]+ z
if ( FAILED( hr ) )
, f: A x0 s/ l( d6 h( f return UPnPMessage( hr ), false;1 R3 ?) @- D% _3 s
x0 j n3 R2 M# R) q
$ {; c- \0 k+ }1 |3 f" o' @! w/ D7 D return wcscmp( deviceName.m_str, m_udn ) == 0;
$ q+ R7 G6 t& N, \$ `- `& v } _/ I- g. i* W$ m/ G
CComBSTR m_udn;0 ?1 v9 j9 c0 _! p/ u; `
};& Q# g/ N* _( V/ \" B
; p( g! A6 S ]! b
void ProcessAsyncFind(CComBSTR bsSearchType);
' u! C( M* f! G1 }8 Y/ X HRESULT GetDeviceServices(DevicePointer pDevice);- e. A8 |# M6 s z c! ^
void StartPortMapping();) ], O# Z5 u+ g. X" f* f
HRESULT MapPort(const ServicePointer& service);1 j5 \. J4 `% z' B- `) v a
void DeleteExistingPortMappings(ServicePointer pService);2 }8 T! g8 i% \: w8 w; L0 t
void CreatePortMappings(ServicePointer pService);5 }- U n1 J# k& G6 b3 Q
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);# K/ c8 n! h3 p8 q4 F4 D
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 6 s# M% W/ F5 w, e# b& i
LPCTSTR pszInArgString, CString& strResult);
) k8 n! h; R; k. l) O- l void StopUPnPService();' j: _7 U3 L0 N6 V' I3 o5 |
# F$ |* u6 G9 I* ?0 y& ], O$ X; n+ l7 r) C3 S5 p) v# T8 p/ d4 K3 v
// Utility functions
. @3 i% U b8 p$ u, x HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
+ S6 a- o* a; X1 g$ R INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
# [ O& N( d+ {$ d- N INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);* U4 U: x0 A2 S7 O
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);8 K5 k/ k0 I. B/ t4 n8 m
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
3 `1 m) Y- b R- C7 v0 | HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
& x( D) l. F- V9 O+ R8 } CString GetLocalRoutableIP(ServicePointer pService);3 D. I5 R% u0 L( X
9 Q$ u% ?$ C& `& T* t' P
1 Q' B! X6 C! M! n( e8 w8 m// Private members
; w- o+ U7 F7 k6 t. h8 d. yprivate:' {7 e9 e8 E7 _, f
DWORD m_tLastEvent; // When the last event was received?* E: v' p& H {$ J' I3 k l! b
std::vector< DevicePointer > m_pDevices;
1 r9 V' @" v) C. c2 w) l" b1 A d std::vector< ServicePointer > m_pServices;
3 S' w% N. f8 p FinderPointer m_pDeviceFinder;
8 F9 a) j' {# b& x4 t DeviceFinderCallback m_pDeviceFinderCallback;9 I0 z. E9 t% b3 P( {; Q5 m' n
ServiceCallback m_pServiceCallback;( }; {' K! A# t
/ W1 y# V+ \" L2 i. k k0 C
4 e' r% n( E7 m# f LONG m_nAsyncFindHandle;% a$ u! L$ M c* o
bool m_bCOM;4 n- \9 V) M' p% w
bool m_bPortIsFree;
' [7 ~2 r) |9 q. g) b CString m_sLocalIP;
5 }# i, X7 r- b1 @/ r CString m_sExternalIP;% Q* G! s0 c6 _+ n" x
bool m_bADSL; // Is the device ADSL?8 p" }! g7 q/ m/ J: r( j, [
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
% v6 d# \& c! ]9 s o( N' V' q( m1 M bool m_bInited;6 f& }$ X& O$ @( {; ?
bool m_bAsyncFindRunning;
6 g/ a: ~+ \) O, t |$ t! \4 P+ p- s+ n HMODULE m_hADVAPI32_DLL;
" W3 f _0 h" r HMODULE m_hIPHLPAPI_DLL;
6 t q, Y. E0 S/ R+ ~: H: s bool m_bSecondTry;% f# }! a9 T6 F
bool m_bServiceStartedByEmule;
2 Q; M7 d3 Z8 [% D* Q& J bool m_bDisableWANIPSetup;$ d! l, [& A+ u7 U
bool m_bDisableWANPPPSetup;
/ u( e( X# u& v# Z+ J4 q- V' d4 @: c S
/ k T; \7 s7 X2 m+ T& H
};4 B9 y( i0 @ i" i; v5 T2 N u
% N/ R6 f* b" {3 k
( |9 z( U3 N' N( X6 Z0 D3 F) L
// DeviceFinder Callback- [- i% Y! r& y% w
class CDeviceFinderCallback
1 |. q% j' h2 w4 s : public IUPnPDeviceFinderCallback5 u& W5 d0 s$ L; Y; B) F
{
& O) p7 F6 W& Ipublic:6 S' y$ @/ K1 F; @
CDeviceFinderCallback(CUPnPImplWinServ& instance). _( {* C# ?8 \5 N% B t/ C
: m_instance( instance )
3 {- ]/ r: K+ P2 ]( j& j! { { m_lRefCount = 0; }
8 v+ }9 P& `) T2 M' B) Q8 e
! f+ t4 J1 ?; G& S$ o- u" ~
2 y4 W. H( W- Y. R4 R1 t5 A STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
) d$ @0 ?- |/ V" M n STDMETHODIMP_(ULONG) AddRef();" Q9 o* R" D0 n0 m! l
STDMETHODIMP_(ULONG) Release();
# P- ]6 f* x& a: m0 {! B' X! U C# {9 F* b0 _) D
/ L( i) z3 w7 `5 P" b. K// implementation' N8 M x. Y1 r+ R
private:: ~0 l9 Q4 a4 C2 f5 \7 W
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);( v( Z- i& a+ H; [- r" }
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
4 o% {* F m4 k8 D5 o! S0 y HRESULT __stdcall SearchComplete(LONG nFindData);! I! F! o7 U% A7 i9 N* `) _
9 k, K3 ~. P, z3 q
0 @4 [& t+ ~$ f* O9 Bprivate:$ K0 b M; E9 d _2 g
CUPnPImplWinServ& m_instance;
. n) b. X' U9 w/ F1 I2 J" v) ~ LONG m_lRefCount;
$ V/ p( e* F. a) M}; g. ~- a4 }# T. W9 B; p
0 [; S& J3 v) l4 \. o: E. N9 r2 S( a c* i% O! n/ i
// Service Callback ( S! f4 {) b) T& V* L, \* `( g
class CServiceCallback$ e+ ^0 t: J+ S/ ^0 E4 A3 }3 \; a
: public IUPnPServiceCallback
7 }% [+ t! u: R0 S: X3 G{+ \: W# r" d) D. J: T! ]2 _: q
public: S1 Z0 ^' n! r
CServiceCallback(CUPnPImplWinServ& instance)4 n% P* j0 r4 L6 A1 ~8 W) N
: m_instance( instance )
6 u1 {0 K9 C+ F" ?. X M; J { m_lRefCount = 0; }3 `& o W1 y' w( c
/ N+ \6 J" b/ w; K9 S: g( P STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
4 M c$ @- J1 \" q) L' T STDMETHODIMP_(ULONG) AddRef();6 W/ ?& Y" x. B. g! F% K
STDMETHODIMP_(ULONG) Release();
% M# Q8 B4 Y" k1 G; P
/ e9 B, [' s: F5 c. h
% I% E6 E+ L* y6 t! j; r// implementation5 E% z9 J( K u/ J& v
private:
0 k+ D; Q- Y# s @" B HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);0 v6 p" d# f. Z1 H) J1 }
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);& t- ~, A F( R- F' E' U A
( |; B: I1 |! a8 }: e* A3 l: f5 |$ O0 d) n; e; U# Y
private:) ^# m O' g, S7 S3 g/ J6 i; g1 |
CUPnPImplWinServ& m_instance;& n* ^% b: r, S u$ C
LONG m_lRefCount;
8 h! C. \' W; T5 y1 S0 k};
- P4 e3 \* W; M6 W% Q" ~ F' v) |6 |, T
2 J" z% J2 d c4 T$ Z
/////////////////////////////////////////////////
9 f" U' n- |0 ]+ H7 n7 ^; R
0 _/ F1 S& T4 ]& O/ E- _3 b; C- s* L5 C2 P4 A
使用时只需要使用抽象类的接口。
1 P1 _# M- K, {; U% L; |! w' a0 ]CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.1 S' }, y6 c8 t
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.! T, `0 n( p6 ]2 J0 H. W
CUPnPImpl::StopAsyncFind停止设备查找.
- V5 g% R; ]% @' ?. O& _CUPnPImpl::DeletePorts删除端口映射. |
|