|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
/ c9 I6 f" e p4 }$ R& @) s8 D; _4 }. H( A; f0 q9 B* t+ O
7 ]) u* P% @5 G3 W( ~///////////////////////////////////////////
& H. n, E' P1 K) |" g//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.' E [% q$ b7 J ~: b% h2 ]
; y$ O n+ G- I) I! x: D1 ~5 w' j
$ o7 c0 `1 I8 Y- B#pragma once
$ C- }! t+ W3 V, v7 l# H+ a. v, l#include <exception>9 p/ x5 E9 ?1 y# c, R' h' \
4 m5 q" b: R' v5 e# L/ m6 `0 V( s4 W
enum TRISTATE{/ S, c6 u1 }3 A4 D
TRIS_FALSE,3 O. S7 l) F9 u) @
TRIS_UNKNOWN,
8 p! y6 i+ ^/ ?# f/ K4 m4 V1 g) {* [ TRIS_TRUE
- k8 S( p6 d( p- j6 I" J};& z! q- j d2 y7 K- R* w
0 I- t" {# ]& s; E' v, [
/ `% y6 x0 G! q" \enum UPNP_IMPLEMENTATION{
* m2 D% a2 e1 Z9 }$ i; e1 L UPNP_IMPL_WINDOWSERVICE = 0,
# `; m! L L# S6 o0 }9 U UPNP_IMPL_MINIUPNPLIB,
$ M$ T7 p: |; O UPNP_IMPL_NONE /*last*/$ K2 R0 {2 \/ \! m- R. z
};; O V7 `) j5 S% X: V, n
% k( }! O0 m$ t9 M' ?1 N+ w
, m c& V* V5 k2 i: v5 _
5 k( s+ l) u7 L% ~! w+ S. I
: R5 ^3 Y' e5 L% U2 c7 ?class CUPnPImpl
( n6 M. _, r0 ?% O{- V3 O* Z( G1 i
public:0 o8 b2 Q; ~- b3 `( r2 v0 U
CUPnPImpl();4 g; n- r! G$ o3 |9 n/ E/ C/ O
virtual ~CUPnPImpl();
2 q' t' q8 ?* |* H8 V struct UPnPError : std::exception {};
6 _3 u$ X- @4 @# R4 h enum {
, f$ ^0 | w1 x4 f0 R UPNP_OK,
% c, t% ]9 j H' v1 r+ o1 y9 V u2 c UPNP_FAILED,
( `: s! V. o1 N% w UPNP_TIMEOUT
1 D1 @# I3 h- \ f; r2 O( H! j+ C };! l4 l3 o6 e4 {9 [1 Z; d
( ]% v3 _' N0 ~9 O. e* S' z: X- ~- f' n8 e! _' Y* |- r
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
7 {/ X/ O- G [ virtual bool CheckAndRefresh() = 0; W3 x T3 Y* {/ ~9 Q, S
virtual void StopAsyncFind() = 0; o. N% R6 b5 B# T
virtual void DeletePorts() = 0;) x5 C/ S$ l+ `; s; ^( j
virtual bool IsReady() = 0;5 ^; }7 f$ D6 l8 g. j
virtual int GetImplementationID() = 0;
9 O6 x# ~4 K1 t: [- {/ E4 t % D5 S9 M7 s, K; L6 F
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping3 u7 s }1 o! F
5 @& x8 H. V* V2 y9 b) f
$ l: l! _7 F" D# g6 P1 ?$ D# { void SetMessageOnResult(HWND hWindow, UINT nMessageID);
4 A+ C! S9 A: W6 J) I; J TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
& P# r2 `: W. a. O uint16 GetUsedTCPPort() { return m_nTCPPort; }" @# |$ b% Z F/ u4 }" [% n* a, s: C
uint16 GetUsedUDPPort() { return m_nUDPPort; }
+ u* r; `$ o3 q" {& o+ t, d6 S' w5 c3 E6 q* Q- f3 i. q" S
! K* c0 t" H0 d. ]# f
// Implementation
2 n) n- S& p' S: I! o) }protected:
# J# f6 ~$ r" Q8 |) p U volatile TRISTATE m_bUPnPPortsForwarded;6 ~6 l9 Y5 {* {- ]2 ~' r
void SendResultMessage();
6 j: i0 [# u* t6 B& y" P uint16 m_nUDPPort;' n* S7 c' J6 s" Q
uint16 m_nTCPPort;6 Z$ q& x* u; S; l; h- @& E2 _7 }2 ~
uint16 m_nTCPWebPort;
" [9 C0 N' D, C) C! Y bool m_bCheckAndRefresh;
! o. m- G: n6 J' n4 {* y1 T/ `( X+ t; ^$ v& B
" z% c) O6 }0 S
private:
9 i5 L5 h) V4 ]$ }' u6 { Q" c. v HWND m_hResultMessageWindow;, u# i: ?5 G |
UINT m_nResultMessageID;
; @9 ^% K; n( u/ p7 d% O6 V
1 T; \* O. A& E, t; @2 w
) W z6 w6 P* }4 Q3 T- c};
) v* Q- y. s& r& j( K/ N9 k1 }! U9 E
- d8 p! P7 d6 G, h( P: {& w4 M6 W8 r8 B/ \
// Dummy Implementation to be used when no other implementation is available
0 x) a9 _, G2 B' S1 iclass CUPnPImplNone: public CUPnPImpl# z6 E* Q9 K/ [ O0 S+ ], V
{$ ~1 c8 k, X: a- s% U& e
public:
: C/ Y: p9 h: B1 v' J7 ]' ? virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }; m: l- O" q; H* y" |9 Q
virtual bool CheckAndRefresh() { return false; }
3 G: z- v: }2 [ virtual void StopAsyncFind() { }
- I: L& a- O) X2 R virtual void DeletePorts() { }
3 G" j) Y% `+ u, Z2 C9 @8 I virtual bool IsReady() { return false; }
5 U B6 s/ z. ~5 P" z virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
+ P Q- h) h& L; J ?};
! U% r% e6 Q" V% o% `0 _! r
$ l, s, [+ U# ]0 t j/ p' F, h8 A) l$ W. ?5 i# g
/////////////////////////////////////
% _6 V- w4 e7 L& x! }0 ?//下面是使用windows操作系统自带的UPNP功能的子类# a ?0 \' ]8 D" f6 @! ~+ { Q
) W' f: r' _4 a- A. G: v5 D% F; b, }6 j; T
#pragma once
/ B) k! K ^8 A0 M#pragma warning( disable: 4355 )
+ T2 u- c/ g: o, Y3 @. k. T4 h; m, [8 C/ ]
; E/ Y$ E! M9 p& C2 G$ G#include "UPnPImpl.h"' h7 a# ^8 x0 m O2 s8 I
#include <upnp.h>
$ b r% a9 W2 K' a( H; |; k1 B% W#include <iphlpapi.h>1 o) e' W6 E1 F/ ?+ s1 h2 b
#include <comdef.h>6 A7 j: Q0 |0 x$ a( E+ ^8 P" ~
#include <winsvc.h># |1 G6 K! V: _
/ v8 H5 j: [0 I5 H
% }- }3 E1 C9 E$ O) X#include <vector>7 ~# o; {( w) z5 }/ U
#include <exception>* f% v4 P* o: _+ y1 [8 y
#include <functional>
8 ?1 n: o; p: ~
: t7 N3 Z3 d' V' G5 {0 ^
" d2 {8 ~" f' J- B+ {
+ O9 _; T/ p, j2 T" ~6 H9 v8 S1 G+ ]& @6 V# u
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;, U ~! G2 G, o2 _5 X2 T- u3 w7 G6 V7 [
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;# Y5 N# x+ X9 {; z! B4 Z E
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
4 _; c3 O; Z& @typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
2 W$ s% _ J+ v1 Ktypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;1 X) | g+ z# g6 w
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
$ ]- ?/ d% ~1 Z: ^( Ntypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;0 g4 J. g2 |$ _( O
) D1 Z4 z5 S/ Q2 V* i) l; i/ _* O; l6 x8 B- z$ z( f5 N9 U
typedef DWORD (WINAPI* TGetBestInterface) (
& S9 A6 K# n! c0 f IPAddr dwDestAddr,
: y6 [9 x- l8 t+ k- @+ H" z* l( L PDWORD pdwBestIfIndex5 [- g) R! Z. e- o3 f: L
);' ]- |( O1 }3 I& p$ e1 U9 Y
o3 I2 \: x2 H
, w1 K+ E% R$ [8 m
typedef DWORD (WINAPI* TGetIpAddrTable) ( X) p3 L7 r9 a9 D! M* G) O
PMIB_IPADDRTABLE pIpAddrTable,: C. P6 z H( q0 C2 {5 U4 o0 {9 Z
PULONG pdwSize,6 i/ M* e; A! f- _4 B& }) R
BOOL bOrder
# @- g) s2 @) h3 N1 T0 f);7 ]! f* s% t, D# v% c. k% R8 I
- M+ e* A) |6 N0 x$ g
4 _4 s. J5 b1 V d1 V V E. ]typedef DWORD (WINAPI* TGetIfEntry) (
' p n/ I7 G, X& Y) `& u3 P PMIB_IFROW pIfRow
8 x' Y5 w8 M2 u, G/ Y$ ]9 P); _9 l [# m2 J+ P. Z0 K* O: Q
: a9 T3 \0 H/ O( k& Y* A' A1 u( C; j
, t4 W, w, ^9 e# k' uCString translateUPnPResult(HRESULT hr);
. H& u9 r4 n% d; HHRESULT UPnPMessage(HRESULT hr);4 z; ?* `. H! I0 f, [, J# i
5 k; H: @% w7 Y9 x3 j, R* l. ~9 C
# e" s& F) s: s. W/ z& s9 c) d5 }class CUPnPImplWinServ: public CUPnPImpl
$ u2 ^8 H, R7 I2 H' }; ?3 E, }{
+ w; N4 E4 U' f6 m7 J friend class CDeviceFinderCallback;
7 f& h! B$ n# Y6 t' }/ X" I) _$ F friend class CServiceCallback;! w% |2 m- d# v" @
// Construction# l) X1 U8 o9 S& t& S8 B
public:) f2 Z# i5 Y5 |$ n6 C6 U" ?
virtual ~CUPnPImplWinServ();
+ n1 i0 j& g" X( H/ u CUPnPImplWinServ();
' `, c- \: Q# ?- o) d5 x/ H3 u z' U* B5 |+ E& k; R% s2 G. V
: r9 D2 y+ B7 S0 t
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }) X! R$ ~# K! \/ Q0 V, p- p
virtual void StopAsyncFind();9 U0 k7 a8 p7 O% [
virtual void DeletePorts();
+ T/ @$ d6 b$ p virtual bool IsReady();
H% t+ t: W2 \9 x z# k" x; n/ f3 ` virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }& }' ?5 Z( y1 h6 `
& L$ s' m2 H! S9 f* q5 a' q& L* I Z/ d1 k
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
0 F* a; x4 L; @1 ^, M$ T) C. { // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
) K( a) ]3 R' i5 ?- [5 s& i$ ~ virtual bool CheckAndRefresh() { return false; };
7 s: g1 F: P# B9 `8 L5 r2 e! Y$ [) N- x+ V- z
( ~: m1 r* S$ K' K
protected:
. ^; K; t0 v" f void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
, y; {( n: _2 g( u6 c+ _1 { void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);' N& v/ H2 N1 O# k
void RemoveDevice(CComBSTR bsUDN);8 j P+ w( e+ i% x# Y. u
bool OnSearchComplete();: t3 k5 W T+ E; l9 c
void Init();0 L4 P2 g/ x0 F: M
' x+ U% W0 d: K b
: [; s" v# C% u) z1 [( W* x inline bool IsAsyncFindRunning() # o3 m* a1 R6 x3 X1 L7 y: L& q, p
{+ O4 n2 |3 |+ {' R: Q
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )8 N6 G9 M- F1 t: L1 X x
{
) Z: \1 R4 j. V b9 i m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );5 z. b- G# A/ f' C8 L% H; \& w
m_bAsyncFindRunning = false;
% a+ i8 J( S$ ]# o }3 S, H# q5 W* E" T3 q3 W
MSG msg;
; E0 o9 q/ _( i7 `0 Y4 c while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
. B, I7 ]+ A. |# R% S0 Z6 I0 S, \) Z* v {- x q) g- e! i8 u g) ]1 K
TranslateMessage( &msg );7 i9 `0 k! h! f) T$ S1 j: m
DispatchMessage( &msg );
/ j' g1 E- b5 F }
- X) C& a; j2 e; U* ?1 N return m_bAsyncFindRunning;- A) {8 `' f/ S3 w# q
}* n- Y: {% ~; o" K
! }9 @, X$ V1 P7 j0 z
- c( }" t2 S. a, {2 e TRISTATE m_bUPnPDeviceConnected;
# G7 O" W c6 W, a- E. g! T$ S3 P4 ^" w8 M3 b5 ^' w: m0 q
1 l4 e( v" r6 B
// Implementation
`9 ]7 J: \/ F$ x! k // API functions
* P7 b" u" d3 [. |- ]- y8 n1 r+ H SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);$ y2 w3 C' @; d* M. ~
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);, v6 A) C5 z' O' G% g
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);2 j* @ \ D2 G3 ~
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
* f7 H0 Z2 s8 v- Y8 _ BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
7 W u/ [9 ]2 z& v/ W) @, J; U BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
7 {: w% g$ [/ w8 ^, `& W, }( e* w& A. Z
) O, R% i# m/ J) d* @" U
TGetBestInterface m_pfGetBestInterface;9 s8 [; h+ l* _1 Z" n6 M/ S
TGetIpAddrTable m_pfGetIpAddrTable;, J L: [- y! w+ A, h+ {2 F- {, s/ v! I
TGetIfEntry m_pfGetIfEntry;; k. H. y5 l) e) q* C# m. {6 ~
+ \/ F# r2 h9 I f% l' Y! f, r0 d% K4 B F6 P
static FinderPointer CreateFinderInstance();
$ B) L5 q( _! U) {6 s4 p struct FindDevice : std::unary_function< DevicePointer, bool >
( c; k. N" {5 {9 d, M {
1 k. j/ q/ S3 C, `1 S g FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
- c: J8 I1 q+ z* d/ P6 a+ s# c result_type operator()(argument_type device) const
8 M& T/ y! d9 W( `( V$ d {2 I% {- K3 G, Q
CComBSTR deviceName;4 q: A! |! O; K& S
HRESULT hr = device->get_UniqueDeviceName( &deviceName );" F( e& s# M9 j! u( o7 \0 D1 G& u
0 g7 i2 ?7 s( L3 W) d/ Y
4 V ~+ Y4 k* }5 H3 P+ w+ K if ( FAILED( hr ) ): L, T/ y8 I: b: D! V9 O3 _2 `3 s
return UPnPMessage( hr ), false;
- |8 }" t" H! u; U& r k
6 N! B9 M; s7 C0 }# g5 Z% d: N2 B) h4 a1 H% w4 |4 C8 O# f/ ~9 p9 P
return wcscmp( deviceName.m_str, m_udn ) == 0;
3 U2 a, p! a0 ] }
6 s- q2 G8 m( ^+ ~6 T6 f+ ^ CComBSTR m_udn;
0 g/ a' W4 w& M0 f" x. Y };
7 u! P3 A' K8 v N1 \% B
& j. G* C! A9 Z, D void ProcessAsyncFind(CComBSTR bsSearchType);( C- W' U( P9 x! ^
HRESULT GetDeviceServices(DevicePointer pDevice);* p$ d7 Q) d5 U: R) F& c
void StartPortMapping();4 e5 D* V) G t1 h) w7 o
HRESULT MapPort(const ServicePointer& service);: U4 p$ }& k Q7 g
void DeleteExistingPortMappings(ServicePointer pService);# s0 P4 _+ j: @7 |
void CreatePortMappings(ServicePointer pService);8 H$ {' V" {' T/ K- a% i
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
( l. d7 M' |9 |2 K8 E* b+ E HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
$ y" p: F7 h! ?: Z3 Y6 m LPCTSTR pszInArgString, CString& strResult);# z% l( C; P6 J) {9 a, o8 ?2 {
void StopUPnPService();
4 a d/ `2 b' K+ c( f7 e. H4 e1 Y
D: S/ w# S6 y" T% A+ S
0 _. }9 f( j- e // Utility functions
: D. S& m7 Y3 E0 p0 P HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
# |8 ~- \$ E2 e& M* u* j- T3 } INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);" G3 ]4 T: W" H% j! V
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
5 }1 J* S( h+ @0 o( A' S void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
! r. {" ~- U k- h- J HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);; b. ]& v" m D
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
: Y+ Z) `0 v+ G' w CString GetLocalRoutableIP(ServicePointer pService);1 T6 @$ V$ l! H. B
, x6 W9 n* H" i* W! {1 E
! n5 ^4 L2 N# ] j8 f) J
// Private members" \$ E% [6 m$ l7 K6 r/ K) E5 m
private:
0 d9 ?: z. e( P0 w DWORD m_tLastEvent; // When the last event was received?! _- O1 I0 v- }4 d# f
std::vector< DevicePointer > m_pDevices;
2 X6 S$ B( Y2 L- h5 `4 j std::vector< ServicePointer > m_pServices;
; d/ _, W; H1 Z; [1 X FinderPointer m_pDeviceFinder;
, l- c: ]* U$ y% ~ DeviceFinderCallback m_pDeviceFinderCallback;
& g4 }9 p/ q/ V2 C6 [/ h ServiceCallback m_pServiceCallback;1 U, O! v+ ?) o
" `7 b4 }7 ~$ x( [- h; R$ P$ \, k { g" P, T0 W
LONG m_nAsyncFindHandle;# i: [2 [$ i5 G \
bool m_bCOM;4 J* ]6 I) Y# {# f0 [4 t9 ^4 w$ c
bool m_bPortIsFree;* s1 \, k) E! f& z: g7 s3 F3 k
CString m_sLocalIP;9 {! R" e9 U" `) w9 M
CString m_sExternalIP;* y- l* A, H- d
bool m_bADSL; // Is the device ADSL?
( d0 C. U; k" s bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
: x9 V$ k& |" D1 l& U9 }& @ bool m_bInited;6 r( [+ h# n4 [; o. N
bool m_bAsyncFindRunning;6 Y- H1 u3 J8 ^* l5 `
HMODULE m_hADVAPI32_DLL;, Q4 }& r3 h9 e9 X+ p
HMODULE m_hIPHLPAPI_DLL;
' L5 U4 l9 Z7 p {7 c/ g: s bool m_bSecondTry;
2 X g6 M, `0 a. s2 C" R bool m_bServiceStartedByEmule;
/ y% M A# G2 B! _/ t bool m_bDisableWANIPSetup;8 m5 k; F. `. S
bool m_bDisableWANPPPSetup;& {& ?6 c0 v% F. N0 T) u6 V
9 A& d' V& l: x s
/ O/ h+ N# t. y9 c! A};
( ?) _& Z: E" z( D- b; X5 K4 U# o6 {. x; l% E( F
9 `3 Z# `1 K n, }
// DeviceFinder Callback
! Q5 H9 U3 `: a' E/ K0 Tclass CDeviceFinderCallback
( @. P. s3 _8 K. v: y' n : public IUPnPDeviceFinderCallback2 a9 [( n& N& f N) @1 O
{1 u$ S2 M7 _9 P) K
public:. C1 O: f% g& E; `
CDeviceFinderCallback(CUPnPImplWinServ& instance)1 J, N+ M: }7 f0 I5 d. y5 j+ G$ A
: m_instance( instance )
U& ?% W5 c+ a( z8 _1 M: s" L { m_lRefCount = 0; }
- ?7 z/ m2 A: b0 N+ `& l
! c6 l) G( N# V9 C- s; w1 X4 d8 o, T: V6 w2 }) A- }! j9 o
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);5 S3 h5 D, N3 Y/ }+ f6 O
STDMETHODIMP_(ULONG) AddRef();" ^' \0 y* i) I$ k
STDMETHODIMP_(ULONG) Release();
3 A: h, }" }" G; [+ I. N+ U- Q$ [6 Y
2 @) p% K# I. q) p; x" p
6 c J- |# L( r// implementation
3 D4 @5 X! n( J+ A9 I. Yprivate:
+ R2 O" l* m, g# N) e HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
" k I [& i4 L HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);3 K: |! u( ~& N! q) e& I7 N6 \
HRESULT __stdcall SearchComplete(LONG nFindData);) U: [8 t2 t8 C# v
) m+ ^0 s; d7 B/ Y/ A6 H, D# s4 {4 J& C& V7 ?% Z; ]+ A
private:/ x/ d# l1 l) A \9 H& t, s
CUPnPImplWinServ& m_instance;' W9 D; e1 u; Q
LONG m_lRefCount;
+ C- i( n& A2 k2 m};
8 n* z- B( R% P
_5 ]; x& X' [% r8 M4 q/ g8 U3 o
// Service Callback 2 A" Q6 a& k- b2 o
class CServiceCallback
+ ?* Y! d: S5 g! B' R3 r : public IUPnPServiceCallback8 ]9 Y4 d# C, k2 m1 a
{5 w* q" n( f5 _0 ?2 Z! ]
public:
: d4 m/ J Z, P! l% ]2 B CServiceCallback(CUPnPImplWinServ& instance)0 H! _- v3 t% { n6 [" |
: m_instance( instance )8 |6 v1 T, R3 Q; C( Y/ w
{ m_lRefCount = 0; }
! }# q" s# g7 J7 O+ P0 v' d 1 T* l5 ~: Q5 t! B. @* |5 v
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);) A4 Z* T4 h: ~
STDMETHODIMP_(ULONG) AddRef();
! o5 q. b G. S8 J r STDMETHODIMP_(ULONG) Release();
) p' g5 |% K2 m/ {" n
( H/ U I+ Q! A7 R% M1 U$ [; ?( @9 [' z
// implementation# e$ Y1 r9 S8 v1 q% I6 `0 s- ~
private:
( H2 J8 H- ]- X. B9 y+ I! } HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
4 b$ K. \5 v+ Y HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);4 I2 p! m% ]1 k% o$ @/ w7 M# v
- y( s6 S+ g/ x% @2 h( b" ^7 K# i. k% x7 |9 G( D5 t
private:
: y; i3 O! p, G1 ?7 c: e I" r CUPnPImplWinServ& m_instance;
! r* r( ^' @. U9 n: c. a7 v LONG m_lRefCount;
, T7 |- x% s# [9 j- T" i};1 b8 k9 B& l. n4 F( _- w$ K
% ~$ n8 {8 H8 H" g
) v/ e7 m' z4 V% F7 Z& v/////////////////////////////////////////////////6 h, g2 _* x$ E; R9 }5 g0 a
3 |6 D& O5 f& l, }4 _3 M" T* d6 K6 y+ n3 M& }8 N
使用时只需要使用抽象类的接口。6 v, R k' O* l
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
" W w' H ]1 F8 [5 T9 D1 M$ _CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
0 V- b+ M2 i8 n$ _CUPnPImpl::StopAsyncFind停止设备查找.
& O: W; X1 G( n& Q. K7 rCUPnPImpl::DeletePorts删除端口映射. |
|