|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,9 e9 h: u6 i+ P0 C3 k* C- I8 U
( ]9 Q2 V) j7 p" m
5 e6 b# N2 Q8 @) t+ F4 w- r* N- i///////////////////////////////////////////7 o5 W1 T/ E" g6 f2 Z( _
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.% w' C2 ]- X# _- K2 f+ s% d
$ a) c3 [4 ` `" Q* f
# ]! X) }* F# v4 V z% j#pragma once
8 y; X; P+ q' A#include <exception>2 k5 [ l9 o- d9 c) _4 F- Y" P
# |! B# M$ m$ X, C6 \% V! W/ H4 m, m* n0 ^: ~2 [2 r
enum TRISTATE{
7 C+ \4 k4 V$ G0 l" [0 j TRIS_FALSE,7 P0 @2 L, Y! A2 B* F3 Y% b% W
TRIS_UNKNOWN,9 D0 _1 s4 K- H: e7 B; y
TRIS_TRUE: v# d1 r+ x# x! n( g6 ?
};0 y2 C7 \! ^. f3 d1 ~% Q! R6 ]
, Z6 W8 P( ~* Z+ D. V
+ {0 |* W8 I/ b s0 Fenum UPNP_IMPLEMENTATION{
; L; F# ]1 n) c* `% ]7 k. }6 _ UPNP_IMPL_WINDOWSERVICE = 0,/ n( N0 _- k( R
UPNP_IMPL_MINIUPNPLIB,, U' e9 p4 G: S8 ]
UPNP_IMPL_NONE /*last*// Q9 }& s; p! e1 c5 i
};
( o: t/ K" I6 R. Q+ Y5 N8 G$ J2 n/ n2 D. \/ Z
6 J% O N; b. v, Y6 X
+ J% Y0 B1 M- h1 ^( b" ?. l
0 F5 l3 v$ F- s7 }0 F/ Eclass CUPnPImpl
' t$ {- }( g5 X4 _' N{
# Y9 s7 |! J+ r8 V! \( s9 g6 |, ] qpublic:
7 B/ J# m8 P7 a1 H) ] CUPnPImpl();4 `# g, a9 [: |/ ]
virtual ~CUPnPImpl(); m- ^& G) E. O5 y6 {
struct UPnPError : std::exception {}; F) C- \$ V; W5 X5 P7 Q
enum {
+ _' Z1 {7 i+ ~9 B# P' O9 B# D UPNP_OK, O6 `, |! @: ]. G
UPNP_FAILED,, `5 ^* m7 T& s9 t8 Y
UPNP_TIMEOUT2 J! K- u/ a2 i8 }8 p
};( A# f. h2 m- V+ E4 U, _2 j
9 `) o4 w' m+ S: j. h
[4 K, L& p/ y. v+ k
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;6 Z$ c# \% v& h9 l. c# I/ e
virtual bool CheckAndRefresh() = 0;' U" X4 W5 _7 k" y1 j- b
virtual void StopAsyncFind() = 0;
3 ~; a; K" p+ c' h) G, l% R2 n virtual void DeletePorts() = 0;
) t( ~0 O% C% G3 ^3 S5 H* ? virtual bool IsReady() = 0;0 S6 Y+ _; G$ b1 d: J! S
virtual int GetImplementationID() = 0;6 L4 }7 [1 ]4 `: u
* p3 _. F( Q' H8 Q void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
0 s. }1 _& L3 E
1 ?0 U- [/ V3 A) |& x$ s
0 p) Y' T+ A8 p9 ` void SetMessageOnResult(HWND hWindow, UINT nMessageID);
# {: X9 |- p- J9 ~6 e( o TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
. u2 h2 H @- S uint16 GetUsedTCPPort() { return m_nTCPPort; } A u2 p: @+ N; N+ r8 |' H+ p6 h
uint16 GetUsedUDPPort() { return m_nUDPPort; } + K' y& p' a) ~" h
% Y2 q* h: ]2 f2 I& k: Z6 I
8 | f0 H/ @. _7 a' a$ C// Implementation& R, E# U, [3 ~
protected:
% |3 n% P0 G, h" \( B+ a volatile TRISTATE m_bUPnPPortsForwarded;# l# Q. A% h7 g4 T% s6 ?; R" I& g
void SendResultMessage();
. I+ i t4 E3 d2 z9 K, e- K" } uint16 m_nUDPPort;6 e6 L& P9 s2 A, x7 L. g% X5 ?
uint16 m_nTCPPort;
6 C9 V4 V* I' G# Y8 Y$ W. ^ uint16 m_nTCPWebPort;
( g) h$ n# T. E0 R' \3 u bool m_bCheckAndRefresh;& R& V' R) Z. j& o! J
5 E1 z# p5 }% N) T' x1 Y
q z! G; X6 y1 B9 H% Uprivate:) C1 j, j U2 }( \( }' H
HWND m_hResultMessageWindow;$ U6 H9 H& Y [0 ^% R. n! D' l* G
UINT m_nResultMessageID;
- D. w( M s3 I* K* m
% p5 y% V4 U7 B3 C) Z) z1 q3 R: G9 l: N w z
};
2 ]& {& W3 Q7 a# q: {% ]) [- q6 {) z0 A4 w* `2 \1 u
$ L0 f3 V8 d; V8 \5 P" o& \8 h5 d. H3 W// Dummy Implementation to be used when no other implementation is available
# z4 N! w. }3 {2 }. f+ A! P, u0 fclass CUPnPImplNone: public CUPnPImpl1 c+ ~2 o0 \" V
{. }5 @1 r" s* } s
public:
( C1 A1 c" i7 c& u6 [$ c virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }/ j' L( L0 L e& B6 a/ x4 ? C. P0 A
virtual bool CheckAndRefresh() { return false; }' \+ k% D" v2 k' H: z- c
virtual void StopAsyncFind() { }& Q- s- d9 |5 r
virtual void DeletePorts() { }+ D( G+ E7 M0 e1 j9 b
virtual bool IsReady() { return false; }
# g8 K1 O: ^! Z. d' ~7 Q, k virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
, u; F- j, Z, t/ M};; P0 N m+ X2 _* B7 V% X& U
) s5 ^9 _ ?; p
; |4 _" i* \- ?3 M# ~* _) n, j. \) R5 G/////////////////////////////////////6 W1 P7 M! s' L
//下面是使用windows操作系统自带的UPNP功能的子类
: D% Y. ~! v/ B# S- s3 |- I
g/ \$ @! ?" X
* A% e9 ~- U2 h/ P' r% t2 x: h#pragma once( q- |5 o3 c: }' L* C2 W, x* _
#pragma warning( disable: 4355 )/ h8 [- F) r& J, P. z7 |
4 b2 F% p3 _6 \* }8 E9 ?' B$ O5 |
3 u6 f. @! s ~: o$ ]+ T4 Q! T3 J#include "UPnPImpl.h"
1 |( E W' S' B/ y, }' k- {#include <upnp.h>: s0 A0 |- u- E7 W
#include <iphlpapi.h>
5 d9 K3 z+ E. d3 p& J/ j3 Y- H#include <comdef.h>
) d' u9 X$ [5 o$ e9 x1 y2 z; [% m: ? |#include <winsvc.h>! X) b/ g3 S* ?" n' H2 \
& F7 R8 J& M. H" Z% \
$ F" E$ U2 |* `#include <vector>
( u s5 }8 @5 j& ~#include <exception>* p; v: c! E/ I2 D6 @1 x# w
#include <functional>3 S7 B9 e3 {" Q, E; s
z" u! G& M! Z( n5 q1 x+ P# t# C' q2 u5 g* d# v, y, x8 m
& v# i9 g o2 z# b
( |; w+ ]$ \3 ~typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
7 {% e! [8 ^$ u4 ktypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;& K0 a) j9 g# p( F" \$ J
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;+ ^6 ~1 E. ~/ p) ~( p
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;& H6 G( V" l6 T
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;- K: p3 I, Y2 ?: O
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;! c; O" \& {! q" I* P% y
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;4 n, \. o( B2 e2 ]: n$ U
- P) ^1 U4 o1 n8 P* `8 f* V
( k8 ]% j+ j9 g4 t
typedef DWORD (WINAPI* TGetBestInterface) ($ k3 ^( d$ O4 M9 ]7 \. c- b
IPAddr dwDestAddr,3 x; ~; c* j9 Y/ } T* R9 A
PDWORD pdwBestIfIndex- ^: C$ G0 }& a: _3 H( _
);
7 _; B; g/ |+ w% _8 o. H0 W8 _( D% z& k7 T' M# k! Y
: e) G k! F, S, \. l# u) x2 w
typedef DWORD (WINAPI* TGetIpAddrTable) (
; g6 l* N) e+ G: T PMIB_IPADDRTABLE pIpAddrTable,
% D4 ?5 E+ X) c8 q1 p PULONG pdwSize,
; j: _- F# {, o6 B3 N( a BOOL bOrder
8 d8 v7 u8 ~* ]" ~2 H5 f. w4 G);) p4 @+ N7 S% f' z; h* t
5 Z' ?/ a7 L6 Y( }0 {9 [$ v$ Z9 h/ u
0 |' U( k- C9 stypedef DWORD (WINAPI* TGetIfEntry) (
1 ~1 e) N) V2 p; h( v+ T PMIB_IFROW pIfRow
H5 V# P" X$ N4 w' A);# r4 u: I, [: H5 f' K: }$ t6 r r! R
1 H$ i% v3 ]- T5 k
3 w; x' D1 E% p
CString translateUPnPResult(HRESULT hr);
2 O, Z. p2 w. O: b PHRESULT UPnPMessage(HRESULT hr);
8 y) X+ f m E2 m) Y& ^* A
: D3 h! z" G& N0 w- G- _+ a8 N& z S. Q1 q8 \8 D
class CUPnPImplWinServ: public CUPnPImpl$ Q( J J, x+ C7 n7 ?$ Q
{
. J4 @% B' d9 g) G+ i0 ^, L friend class CDeviceFinderCallback;& [+ b7 v1 ~5 w% ]) `
friend class CServiceCallback;3 w" Z- D, m7 T, Y
// Construction
9 m2 y+ z- l* q; ]3 Upublic:
/ e( C6 i. s5 l! ?9 K T/ U2 c virtual ~CUPnPImplWinServ();
' \0 a4 H2 R0 @( M- t& O CUPnPImplWinServ();- H9 Q- b$ O+ L5 j C5 ` _
; r# d2 M3 t0 q3 Y' p. a+ L8 P! K
' h# L, Z8 H* M virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
% u2 g3 I3 B) b# V) b virtual void StopAsyncFind();
( C/ b- \4 F& q: l7 y virtual void DeletePorts();7 d. M l; X1 W
virtual bool IsReady();$ |* F/ g% t8 L# A( M. m
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
3 i. V' | l, Z* N' w/ L! o2 E1 \$ O; O% h7 {
" B7 Y e- e% H, n+ h) J
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)( I- }+ v# [! q- y
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later6 w: m% W8 q- Q0 A4 h
virtual bool CheckAndRefresh() { return false; };
; A0 |" g8 x& T* A2 U8 N1 [ z. |4 C* K) H6 v
4 F3 ?' h" G3 Y7 f8 }protected:! }, M" c' ^" ]: f
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
9 u/ Q( `/ }& R/ ~% f5 X void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);( T* R# o" ^( \+ x w% P% d1 }
void RemoveDevice(CComBSTR bsUDN);4 ]) }5 b' o' I+ k: u: Y9 e
bool OnSearchComplete();
1 \& g" {; w$ m9 Z9 j void Init();; z+ x4 \: k2 A5 H$ A% S
$ F% z7 T9 E) m9 ]6 r3 h1 r) W3 m( C( }7 y5 B/ ^2 W1 o3 R' _: k
inline bool IsAsyncFindRunning() % y. g6 W# h- d! i; I/ I
{
0 [9 C; C# c/ J% q! N/ o3 v if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )/ q. L5 @& d* p" w+ s4 `
{
4 Q" i* P+ @. \4 H4 { m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );* U0 y/ t- L1 t% l
m_bAsyncFindRunning = false;; l5 z6 L8 ^( o& b
}
3 ^0 |* F* Z5 A' y" C MSG msg;
6 Q+ {, V: Q2 d( K while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )# ] l" L8 s2 L5 F) a- a. P
{8 {) }; J( M" b$ R
TranslateMessage( &msg );2 J2 R& c( `" v" Y! N
DispatchMessage( &msg );
; B6 e: S! a" Q }: j6 |3 R8 i* C6 o+ v& r4 Q* l( p v, A
return m_bAsyncFindRunning;; K3 n" E; X; f: x Q% D
}
7 v4 O) Z$ `: |3 D; \! U6 w9 z$ A E7 O# e: Y
. P$ [. D4 k" E4 Z8 y* N TRISTATE m_bUPnPDeviceConnected;
$ k2 u& a% ?6 N. U# l0 J. z2 [2 A( e# x+ ?7 i: U
5 }% {3 S1 Q& |+ }, M4 Q5 b4 ~/ q% v// Implementation
8 ?- {$ {7 f% I8 `2 C4 E5 K // API functions
* B, g- X3 O, ]/ @5 { SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
9 }" P; `6 m2 f" f3 C. C+ t) i; X! |2 \ SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);) D$ m+ W) S9 R( \8 Z3 F: b
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);6 t: l' s f: ?9 f
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
4 d1 j, e* L+ x BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
7 F9 J3 M9 @: b8 \ BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
. M( X+ O3 p1 U% V- O1 k3 E
* I1 X" Y3 g$ H- s% G5 y. @3 j
2 m( C+ B% A5 L2 |/ f3 E) V% a TGetBestInterface m_pfGetBestInterface;
! b" j2 {/ Z$ @5 O2 z+ p TGetIpAddrTable m_pfGetIpAddrTable;
5 O* j$ g, F. F0 J0 \7 U' g TGetIfEntry m_pfGetIfEntry;- @9 k, ? t* y; T, X% l9 O+ q
( p0 P9 o6 W2 t& J8 I) |4 W7 P- P
: v: E% N3 H! n3 l: s static FinderPointer CreateFinderInstance();
% ?" d" ~* Y7 a9 m" W3 E3 V struct FindDevice : std::unary_function< DevicePointer, bool >
0 t& n8 m0 H- B' y: a: a; _ {
# J. l; v" R7 [& m FindDevice(const CComBSTR& udn) : m_udn( udn ) {}2 v6 [) }, C" R, Q* X9 L
result_type operator()(argument_type device) const) @' b, I0 S0 A4 Q/ Z$ ]" \* ^
{; w. M2 v( q) b: t1 t
CComBSTR deviceName;
+ K& ^" D5 {9 E9 l+ G7 ^$ C8 p8 p- q( G HRESULT hr = device->get_UniqueDeviceName( &deviceName );9 T# W% e9 T/ I7 @% Q
# r! w7 v+ x" I' t4 {# K+ [
' f3 g1 S2 o; N1 {' P# v
if ( FAILED( hr ) )* R3 P8 m# W, i4 \# d9 o, o
return UPnPMessage( hr ), false;
" [4 t0 h- ?" \9 J+ Y! w5 H+ w1 M
; J1 W; z* }' z return wcscmp( deviceName.m_str, m_udn ) == 0;" y9 U' X, C, [6 X V
}; i) g" n% D3 n) X# D* |4 _. {
CComBSTR m_udn;
6 A* L$ P5 Y, E3 @ };/ o( c, c+ Q! h3 G3 f8 y
0 h" X" D' }9 ^/ ?9 N& ?& Q void ProcessAsyncFind(CComBSTR bsSearchType);5 z4 f( B: ~) t. e5 Z
HRESULT GetDeviceServices(DevicePointer pDevice);
' ?: U2 e( R0 `7 i( j5 r; l void StartPortMapping();
3 b3 E" M, A, } HRESULT MapPort(const ServicePointer& service);
! O5 X6 S: j5 ?1 k5 G void DeleteExistingPortMappings(ServicePointer pService);
8 H* I) l. T: t+ `) S; ^, z void CreatePortMappings(ServicePointer pService);
: m0 o- `! ~' c! y2 b" ? l HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
0 ?5 [% z6 j, y+ e3 ?- o6 u- I HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
# n8 }( M. b' Y! c U" f) h3 H LPCTSTR pszInArgString, CString& strResult);
9 z' y* @( e1 Y7 }) y void StopUPnPService();
6 B% ]# S7 a; x `2 N( \% s& x8 W3 y9 [/ P2 N/ @0 F! m/ S
, |& x* ~7 D9 R // Utility functions' i. R( g$ O1 m0 }/ S/ m' N4 `; V
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
8 w# I" G% V# v: I5 j- G) \; | INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);9 p: ^( b/ Y" _! _
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
! F. Q0 i+ w6 q+ s$ F: ~ void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);: }8 G" p" C. y2 Y5 [3 g
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);/ B5 A+ v6 g1 V; z- Z' v
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);6 X. \+ K9 @3 ~% _" P
CString GetLocalRoutableIP(ServicePointer pService);4 r1 e: y$ a4 T( W
) `7 L6 ?1 b: ]
0 B+ y) b! V" m$ D# a// Private members
& U+ _* l/ s% q4 e% C8 J- @" c. N9 [& {private:
; x, O! M r% C. M DWORD m_tLastEvent; // When the last event was received?
: Z5 B) [! v1 X3 G std::vector< DevicePointer > m_pDevices;2 g: f6 ^( \/ K8 L) C% O
std::vector< ServicePointer > m_pServices;8 T$ t3 X% g, P; @% [, I
FinderPointer m_pDeviceFinder;3 U2 x0 M8 V3 o! {& Y# V
DeviceFinderCallback m_pDeviceFinderCallback;$ G& h$ |& Q0 p# Q6 G; m* A) q! o
ServiceCallback m_pServiceCallback;
5 N2 g9 ^- {' j6 D2 r
' _9 b; y6 Z# P, q+ l6 f3 n
, t7 Q& m! T l LONG m_nAsyncFindHandle;
* ~4 Y) D/ r, O8 {! T# t/ u: V bool m_bCOM;
1 T: B, S0 \4 i. G/ @; P* h bool m_bPortIsFree;
7 I0 ~4 H) A' D. w4 `% O CString m_sLocalIP;
/ g) D% r9 W4 r CString m_sExternalIP;2 J6 e" f. O7 b9 q: o/ a1 ?5 O L1 L
bool m_bADSL; // Is the device ADSL?6 X, N$ J% c( n. [6 u+ s
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
; A* z. W/ c: N1 u2 q$ p; B. ? bool m_bInited;
2 t. U- S( `+ V9 w bool m_bAsyncFindRunning; x" H6 o D3 \7 D5 W, [
HMODULE m_hADVAPI32_DLL;
5 w5 ]0 N$ ]0 Z a/ U1 A: \ HMODULE m_hIPHLPAPI_DLL;, I6 Y' I" |( r5 f
bool m_bSecondTry;
9 |0 q% n6 I1 V) v) H/ t; R bool m_bServiceStartedByEmule;$ r$ X) e" U# Y8 K2 W) n, l
bool m_bDisableWANIPSetup;
: A2 Z3 L) P/ ~ bool m_bDisableWANPPPSetup;) Q9 \7 [% c& K: N% p8 q
5 e7 b8 y% z$ W- {0 w4 J# {( u& F' p: }( y* j+ L7 D5 A& S, P+ Q, X2 b
};
( j' `8 r0 I# [3 o7 b; c q' h% I
9 D _- f% O/ e: z// DeviceFinder Callback
/ i! N% j& H0 j& T9 \1 qclass CDeviceFinderCallback
8 H! v! H1 R# a& Y5 @ : public IUPnPDeviceFinderCallback* ?1 f7 F" u$ a7 g+ h
{! Q& X6 T$ ^: j
public:
- L' i f) I) ?8 O! K! L; P' N CDeviceFinderCallback(CUPnPImplWinServ& instance)+ E6 }# @: ?% J# c
: m_instance( instance )7 H& h: F' d4 j9 E: T
{ m_lRefCount = 0; }
2 X/ Q. z( D! G! Z
8 b; K. b3 `- p6 o
3 J. K: f3 i1 z STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
1 K) F" J/ y& [, Q$ z2 D [/ w STDMETHODIMP_(ULONG) AddRef();
# g# o, e; m/ e( o9 U+ ^2 R STDMETHODIMP_(ULONG) Release();
3 r$ Q/ y) ?: ~% i7 g# X9 }) e4 ]3 b; s* ?5 p; ]4 U
8 x6 \& h( P% m) Q& U
// implementation0 \; }, j' O; G; O0 b' M% k) O- ~
private:
! Z4 \; M; a) j0 V; j$ N8 { HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);1 z& k& c& H6 k: p
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
7 C) o" Y# x8 \0 ~) |/ q | HRESULT __stdcall SearchComplete(LONG nFindData);& Y% z4 l# Y& Z) g
( Q/ B; v' i% {9 K7 w8 P. r% D$ V' o$ h2 [
private:
* R' ]: U) T8 N CUPnPImplWinServ& m_instance; i) W" D [/ q6 Q
LONG m_lRefCount;
2 N. H7 P' q: L- T};
?" Q2 c% d: X9 q4 w0 L6 {2 G
+ ?* N; |( y/ d
& D D, E0 }1 T& }3 i// Service Callback
: j- h- O" n7 P7 Q2 Y% ?" Hclass CServiceCallback
& h; O% Q" a# q5 u4 U! s8 j* Q e : public IUPnPServiceCallback
) y5 b5 T: g' |8 H) r0 T+ ^{5 P+ d: ]! ~" O1 o( e; g
public:+ E, N9 X1 ~& e+ T
CServiceCallback(CUPnPImplWinServ& instance)
/ {$ @- h; Y3 _, X : m_instance( instance )+ R0 e% K& d5 e- W* N$ R1 a$ N, m e
{ m_lRefCount = 0; }
/ A# K& O+ M- g: L) @$ D
: s$ a! B, Q; p- z) R0 ? STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
) f/ i4 t2 n3 C5 K; w STDMETHODIMP_(ULONG) AddRef();5 D! M) i( O9 y* R
STDMETHODIMP_(ULONG) Release();
# A; ? E' M! }) q1 a
0 W) P8 I" R- y/ K- ~0 A4 K) ^) F8 h2 c" A
// implementation/ w# f% h/ J2 G$ s. Z" C& |
private: i1 T5 T2 l3 q
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
. H: k* q5 U/ |3 e' y @! A HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
, E% C! _8 W$ d! g7 z5 B L. X7 {6 [2 P8 o5 d& |
* d% B ?( j! z. s2 h. X. J
private:
' h1 J$ G# Z# L3 C3 h! Q CUPnPImplWinServ& m_instance;3 T) o( l2 U2 X4 K& Z1 f' ?. |: g
LONG m_lRefCount;
$ Z9 d6 X: G1 r};7 ?8 T5 z9 b! O* C5 p; m
+ h7 `+ Z# q: K5 U# a# a& [! f
2 r D+ k( ?9 m# R/ H. B J
/////////////////////////////////////////////////
" Y0 e; o1 p% H7 X5 M1 r# S
% V( j7 j2 E/ d' }9 d7 ^4 Z7 r( s0 P& q0 ^% q2 b/ ]3 o2 {" }( A
使用时只需要使用抽象类的接口。 T- z5 u' l \& { o4 G. `& L/ w; ?
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
{% {- H, {& w2 x7 c4 K7 jCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
4 J: I9 S" O; r$ `3 s- S" U# aCUPnPImpl::StopAsyncFind停止设备查找.
4 @* ^9 W. [, R1 z. t( c' J% Q- b6 l% D+ oCUPnPImpl::DeletePorts删除端口映射. |
|