|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,3 D' n a$ N; C) k3 M
. p% ^4 b, }. A! Z
Y! _( V5 @1 I% V: u( j///////////////////////////////////////////
: j' C3 m/ a T T$ y" g4 ^% [) `//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
2 j4 I8 ?( v( p) f* s/ i3 X6 \/ Q" }* L& j" v
- v/ J' R5 ]' N" d% ]: O
#pragma once
0 e# A' }2 ~0 c( b3 K#include <exception>
( }% P1 h+ x) e& { c, ]/ t) s3 c9 d, a! N! M
) V2 f* t! Q$ }& g$ M+ H; R1 ? enum TRISTATE{$ ]7 F2 [9 o( u$ U7 d
TRIS_FALSE,
$ G4 C& \6 Y: Y# b& z6 I( ?$ d TRIS_UNKNOWN,
6 j% e8 @+ F. u) L; o7 L TRIS_TRUE, e& z5 A- F( v& b7 e
};; r! ]& T1 L+ o4 y$ }6 g
# f( s; A. `% d/ U2 A# f$ N* T5 U! H% j4 }4 j0 u
enum UPNP_IMPLEMENTATION{4 l+ `. }" [/ j2 R' W
UPNP_IMPL_WINDOWSERVICE = 0,( K5 B& ^, Y, K
UPNP_IMPL_MINIUPNPLIB,
) Y# K9 ?6 H; C1 N' _! R+ \! m UPNP_IMPL_NONE /*last*/
! | m+ y$ a$ X# y3 s};
3 |/ o% _8 A3 }: u7 ~& W$ o; ~ R1 s3 g- ]5 I
- g* N7 o5 A% A* I
% Q# A6 C* Q5 Y. C( n7 H
. E6 d' Q& V) g3 c4 \! y
class CUPnPImpl1 u- I5 ]( H: t& U
{4 o) A" x2 E% `* `1 L8 j
public:
2 V7 H/ Q+ i! P$ p( B& Y6 M/ y( k CUPnPImpl();5 b+ b7 F: Q2 v* M
virtual ~CUPnPImpl();8 h% I( I; C" ]) z) t
struct UPnPError : std::exception {};
5 `. E; X" j2 p- j! E enum {
8 y# P3 _, R& z8 Q7 }2 l UPNP_OK,
) p9 l3 u! J% C0 v, I9 m UPNP_FAILED,
6 P8 _4 `$ `$ {3 {, y) a! b, _; d UPNP_TIMEOUT8 c+ r5 z/ M5 g$ H1 Z
};' C! \" @' l& j6 _' h' N4 l
+ f' X6 N4 D6 t6 s
8 s) i, _) h( V- j! J9 ~
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
# _6 m$ M' b- G% \3 U. g; X virtual bool CheckAndRefresh() = 0;
7 a# m5 @1 n5 N; @ virtual void StopAsyncFind() = 0;) _" A; ^$ N$ [2 t) X
virtual void DeletePorts() = 0;4 E1 \ d3 m0 m3 E0 ]
virtual bool IsReady() = 0;
8 m( a2 m# o2 g" H0 p virtual int GetImplementationID() = 0;$ n' y9 i7 \6 |! S
4 k6 k% D: k: e2 r
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping, w+ x- x. Q' P5 z& `) S0 e5 R& Z, H
' n$ N" B H" B; P) Q- k7 Y
# v; l7 Q7 w; X4 |# F void SetMessageOnResult(HWND hWindow, UINT nMessageID);
/ J2 F Y; w) M9 { TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
# s- p H$ M) y( Q3 M uint16 GetUsedTCPPort() { return m_nTCPPort; }
# q Q; D$ e$ e1 x uint16 GetUsedUDPPort() { return m_nUDPPort; }
% K$ Y' X8 ?; [! p, N& Z1 S
5 C; Q9 O3 N3 o4 O" s6 L: e4 H! D8 C
// Implementation
5 t% Q z; o+ F. ], j4 iprotected:9 |& L$ o0 }% r$ r
volatile TRISTATE m_bUPnPPortsForwarded;
$ `. G1 d$ l2 S& C, u void SendResultMessage();
+ H+ U) \( }/ \" D uint16 m_nUDPPort;. L [: g& p$ L# k* R
uint16 m_nTCPPort;7 [6 p( U2 Q! e
uint16 m_nTCPWebPort;) k; H/ H; ?& p0 O. \
bool m_bCheckAndRefresh;2 _+ G3 k8 w9 ]* k
( c) Q% D4 r* i* _" ~
3 J! A8 o/ _, i# Nprivate:
/ g2 N M# \' {: {# g/ K$ U7 R! g HWND m_hResultMessageWindow;
* I. X& C& g7 X0 F) R/ U UINT m_nResultMessageID;
& G( {' n5 y& |5 s0 _" C! W0 W# V8 b; W& x
/ Z- y$ i) `! p) ^8 {
}; l/ E5 [/ k7 m0 K7 o
4 x1 a0 M- W$ G) [+ U" t
& p- J Z: b. t. R% X$ y* k0 R
// Dummy Implementation to be used when no other implementation is available* d& `- t S. z$ D) c8 M
class CUPnPImplNone: public CUPnPImpl
1 S. o* q6 B4 R& O$ S8 D7 m{
- q9 U. s; H& D" G. gpublic:3 i3 P* T! f# G+ C7 {
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
. C& V5 D6 P- p% g virtual bool CheckAndRefresh() { return false; } f, ~$ ]4 J# n! x1 a5 S
virtual void StopAsyncFind() { }
7 c/ |* U U5 {! ~( p virtual void DeletePorts() { }
, J$ \9 Y5 J0 K7 k2 l/ C virtual bool IsReady() { return false; }" ^) X1 l7 E" V2 m6 ], L9 x
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
( j! F* l/ N( X+ ~$ C9 |};% t. n9 [% F7 N8 w( m/ ?8 }/ Z
, }# ^3 b$ F) F5 n1 D6 s& g9 N- y3 v$ o5 I% l
/////////////////////////////////////
, d" a8 `/ V9 V% ?# C4 ]//下面是使用windows操作系统自带的UPNP功能的子类
" Y% E- c# n! G' S H
2 Y; r" T2 p* P
$ D! `/ ?% f4 {& q8 Z, b q#pragma once
; @0 i3 E2 m, X! C5 ?#pragma warning( disable: 4355 )
$ r9 C- c5 j! C7 E
4 Q( ?$ g/ S+ L8 h
! S. s. t! A! E5 @% q#include "UPnPImpl.h"
s3 q, V3 D& i! f i#include <upnp.h>* W. f `9 }; T0 `# _) G8 M- V' `& X
#include <iphlpapi.h>( Q7 \; R- c. I
#include <comdef.h>
2 n0 E& S$ k2 z* i+ d- [& d#include <winsvc.h>' g' i8 U! J n7 i7 q' ]' k& H1 ^. E
$ \0 b1 ]5 [+ R3 s
* |7 L' [* F' |! o, J#include <vector>4 p5 p- r ~! n% M3 f6 @ j8 X
#include <exception>
# h; h$ \, S" c2 ?$ ] n c8 k#include <functional>
" U3 L' b7 I' Q7 V% X, i
& l' R" \; b+ H. T; R/ g% J+ M8 h- \$ ?, ]1 B( w
0 L9 _* k0 A) ~
4 j) @, N; J! C2 W8 s, a9 Atypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer; {% }+ I2 C) u( J" K7 `
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;% M5 m9 u8 l5 `2 ?* e: j
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
! |" ~; ^8 ?7 ?$ T- K, |6 ]/ W& @typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
2 e3 v8 _6 W3 m L) y% }( O+ Ptypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
; Y4 U. L4 M$ j0 i) b& a- mtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
5 d9 N+ X6 Y& l2 k% G& L utypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;2 C y( S" T( \' w2 C9 }. j( X
; C5 \2 p* Z/ C. d3 Z
$ [- b V+ i( J: r$ a% ltypedef DWORD (WINAPI* TGetBestInterface) (
5 q& C- l4 i3 d/ s) a: } IPAddr dwDestAddr,& Y* _: ?2 d" M$ q
PDWORD pdwBestIfIndex
+ @: g7 _% i8 j+ W! q; v8 W: Q);
+ j9 ]$ L, @ z ?7 X; Z. j
! b& S) A! b2 p# k d9 J/ `* Z- c" Y, g" g; J' f; Z$ b
typedef DWORD (WINAPI* TGetIpAddrTable) (, U3 Q0 {, T. H+ @4 Z: ~$ E
PMIB_IPADDRTABLE pIpAddrTable,$ U$ t" k" C6 l6 M1 K: X; B
PULONG pdwSize,
! V6 v9 q& u5 B6 s: T8 g5 n6 K' d BOOL bOrder- h+ ?4 l8 ~: M Q1 f' w- o
);
& W# p- u# Q& P$ y1 w/ U- h5 _2 z* M4 B: Y
4 I' ~2 x* z9 W3 R
typedef DWORD (WINAPI* TGetIfEntry) (- S- m4 ^; u1 c7 t. a
PMIB_IFROW pIfRow& H1 q9 F- s# ~. s) f
);
6 q c/ F0 w' A6 @
9 M7 d& |# J2 {( j r( c1 Y8 X8 O; y! ]. I8 l
CString translateUPnPResult(HRESULT hr);
( {/ i, Y* {" P& PHRESULT UPnPMessage(HRESULT hr);
6 l$ d5 O/ o! ], Z- N' D! x/ t$ {! t# d# j; U% v6 P
& ?" M5 k @- i$ V
class CUPnPImplWinServ: public CUPnPImpl6 ]* J% j- C; d; M" E
{- [ ~1 s- r% L) j& z0 W# u$ B7 d
friend class CDeviceFinderCallback;
# k i7 K5 @# ?. i6 U friend class CServiceCallback;
" `+ `- e7 `7 F, r8 S// Construction
& ~- s% t" D/ `( s( A7 ~public:
. X( s6 G) N( o. F5 q ^ virtual ~CUPnPImplWinServ();
) N' S5 m' W* G& V7 p+ B# ?- S* E CUPnPImplWinServ();
b5 G/ n( ^" K+ O" W
7 g$ w/ j8 N4 y
3 d+ `. Q( C' n0 g! B4 v$ O# { virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
* e4 i0 w$ z' [) D4 X' R2 O virtual void StopAsyncFind();7 M3 @9 `4 {" P* {) g0 D( Z
virtual void DeletePorts();
+ F* A! G! ^" a3 w$ X% Z' N3 f" t virtual bool IsReady();# _. [) B7 E! J/ f
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }7 n* W5 i$ {3 f
" g1 R$ g6 f) T2 u8 Q4 f3 t9 P6 ~0 F ^
' W/ E% M# q# I- w: Z# m% J
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
- J9 G& k1 j4 g' G // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later, U5 s0 C2 G) u) k! U
virtual bool CheckAndRefresh() { return false; };
' y4 `: u7 h- B. X$ K! l$ x9 |8 G. f. b; w* \
; u+ R$ M0 u W4 b0 S: p
protected:
, Y4 p" |+ Y9 j0 ^* \, K void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
: _6 [$ @8 G* f: n/ o. N8 `1 L8 f" B void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);, }: V0 D4 y J/ \/ K
void RemoveDevice(CComBSTR bsUDN);
, P" L8 u$ ]9 o# ?3 C1 A" a) p% | bool OnSearchComplete();- [/ b: s8 k8 u2 d8 F3 P
void Init();+ b- N/ p6 i- j+ X/ _) A( p& b
6 D) p( l# t) k4 ~2 m; R
( T( Y4 C4 [4 [3 ^ U7 K. \6 A! c
inline bool IsAsyncFindRunning() $ R: \, W$ n8 ?* q D( W
{
! g9 J! }0 z8 o8 Z) E& R2 X if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ): r* ^4 h d/ o! x( I5 I
{
! R8 }/ Z i$ \% w1 M; u m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );" M+ B; l6 e! ?! w
m_bAsyncFindRunning = false;9 d3 f$ C+ X: c& \7 t, Q. D$ [
}
0 z) Z- c6 A: @3 A" C MSG msg;
* a2 Y+ M, a" b$ T while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
- W8 g1 k1 \. K/ v0 V" P5 w {
& V, r; }% d3 l8 p1 k9 O TranslateMessage( &msg );0 d9 F6 v8 ^6 ~4 @5 A y. x
DispatchMessage( &msg );' E r$ z, N* ^5 m
}7 K+ c6 ]! x& n2 o7 A( x0 k
return m_bAsyncFindRunning;9 R( |4 k& r3 t( J
}3 V) P6 U8 O/ x4 n% B
0 J9 `: q. J% @: d" I
# R3 i, `. `0 h6 c6 d9 r, m( V TRISTATE m_bUPnPDeviceConnected;: ^2 c7 P) U {: |; D9 y$ S0 C$ e
1 o0 M6 x8 i9 x; B, P. D u' w
) l# o Y& B) _( U
// Implementation
) [* a+ H2 A* \7 Y7 Z$ e( A* N // API functions
: P, ?8 ^# t+ `& v5 Y0 O; L SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);3 Q: q Y. l9 y0 R, W
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);1 W/ v" g/ q% g7 P/ |* x; X3 E. k
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
P! @" _5 ?# L: u BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
$ y; p3 }% b1 V; B BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);9 ^% d+ l5 N" L9 M, \8 j
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
$ E+ @( F5 T w5 ^3 R, P
1 T( b) [! |! o6 B- ]# `) C8 n* y! v* i0 x/ x( N
TGetBestInterface m_pfGetBestInterface;; X E" h; M( D. B9 ^
TGetIpAddrTable m_pfGetIpAddrTable;
( d5 S& z$ X# K TGetIfEntry m_pfGetIfEntry;. y# D7 M5 z$ m4 v' d- }6 l
' Y( R7 w4 @ \ B
0 I& R6 |9 r F8 w$ A% v, l static FinderPointer CreateFinderInstance(); Y) X* M: C$ M7 ~
struct FindDevice : std::unary_function< DevicePointer, bool >
4 ~+ |6 p! W1 \: J0 u; N( @ {" @4 `: X" F3 M, [9 v
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}+ Q# R. U+ S$ T% I D! [
result_type operator()(argument_type device) const
6 w* p) ]. i+ i5 j {
- x! M; e1 R0 P0 X& ~ CComBSTR deviceName;+ a/ L3 H4 x A3 H% R* J! M8 J
HRESULT hr = device->get_UniqueDeviceName( &deviceName );' h9 H0 T+ q; b. N' c
" ^. v# V- D$ {3 S" N# m. W- [
* R' g, H% \* ~! i' {2 X if ( FAILED( hr ) )/ O6 U( e# o6 R* S% z' B% ^1 o
return UPnPMessage( hr ), false;
, E% ]! D4 C0 ^; H. r% h; J- y, G1 z0 |7 ]% a6 @ F
: a' \1 P" w+ @5 U1 l return wcscmp( deviceName.m_str, m_udn ) == 0;; U' N/ |- H& M7 ^$ x+ {, i
}
" y$ e* j$ g k CComBSTR m_udn;. `7 V6 t: E2 ^7 g" H
};
) X/ x$ C/ s! R6 V+ f1 i 8 w; E$ S0 q: j' Q- r. ?( u5 h
void ProcessAsyncFind(CComBSTR bsSearchType);
6 U/ q6 A* F9 {9 H9 d0 u! p HRESULT GetDeviceServices(DevicePointer pDevice);! E8 a# U5 k. }/ _
void StartPortMapping();& t1 u4 V8 Q: b% A
HRESULT MapPort(const ServicePointer& service);
& P; ]: W3 j- g/ B% N. ~ void DeleteExistingPortMappings(ServicePointer pService);% `0 }5 \4 l) p5 O1 M, H
void CreatePortMappings(ServicePointer pService);; ^8 W8 ~$ \- o$ e" G. c& ~
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
2 u0 P8 ?# o$ A: c( U4 N8 G Q9 T* j$ ] HRESULT InvokeAction(ServicePointer pService, CComBSTR action, ! k3 q; N s* o" K" a6 H5 ~
LPCTSTR pszInArgString, CString& strResult);# r, J v2 ~( ~# ^: Y' m; L
void StopUPnPService();
* ?) P5 `# `6 M" i
' }: k& [( j# R- P7 f; V) \1 H7 j3 ~( r1 q& ~1 n: V1 z) b% B
// Utility functions" l% |; x) q. W
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
8 C( h, s$ Y5 X' w! V0 I+ e8 t% ? INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
+ K3 ^9 K+ \5 \, \ INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);( K' q) S8 ?, X" v7 ^/ }3 \% J) ]
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);3 i5 Z }. {+ ? h5 z
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
5 W# h, A1 y' d4 u! Y8 U HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);3 G) i8 K" H5 J6 J4 a) F& n
CString GetLocalRoutableIP(ServicePointer pService);
S8 K3 O+ d: A- l! ]: n, l9 k% H, w! k* F
4 K* d5 |0 N- k4 X, s
// Private members J' T0 B1 K5 K2 \4 A# W% j
private:9 h7 k# l) Q: A% q7 A+ ]8 e' c
DWORD m_tLastEvent; // When the last event was received?
4 G$ Q7 }1 c7 E; \! I6 ^ std::vector< DevicePointer > m_pDevices;
: W2 m; B. ?! U std::vector< ServicePointer > m_pServices;$ U7 R0 O4 r0 f9 C! p, N
FinderPointer m_pDeviceFinder;
6 u" G: W7 u& m8 n DeviceFinderCallback m_pDeviceFinderCallback;: j( W# K/ L( C& |1 @9 n( x2 k
ServiceCallback m_pServiceCallback;
. @- `1 c) s: q+ N6 _& X% D7 n1 i) ^
+ X+ g% ?4 S/ u* @* ^" K' Q7 x2 p' Q0 k# r$ A
LONG m_nAsyncFindHandle;
4 V3 R8 O I, N- {0 T `/ @ bool m_bCOM;$ J' b6 A+ n/ m
bool m_bPortIsFree;( S: O8 ?2 \. f( m% ?* W6 @$ ~
CString m_sLocalIP;5 J- r& {# U9 K% s5 @7 I7 X
CString m_sExternalIP;
6 a3 \% p9 a# j+ ]! I8 p" f" f bool m_bADSL; // Is the device ADSL?
9 D' W! @ J4 a" P7 `1 L bool m_ADSLFailed; // Did port mapping failed for the ADSL device?0 o. A$ u0 X; c# m
bool m_bInited;
% p5 J8 N. A* y7 f0 Z% B0 S bool m_bAsyncFindRunning;! ~$ c4 @# l9 J1 d
HMODULE m_hADVAPI32_DLL;
6 J. n1 u6 A6 x. M4 E HMODULE m_hIPHLPAPI_DLL;
! }9 r" u- N& L( {% M bool m_bSecondTry;
, ?+ }' U8 G0 k- X bool m_bServiceStartedByEmule;) p" T) M5 K$ N: q
bool m_bDisableWANIPSetup;
. k1 x' M+ P& j bool m_bDisableWANPPPSetup;
. c* M3 j5 W" b4 B
- ^) I9 H5 J0 p( Y/ G1 O
+ w: W" j2 F# d};
+ l9 Z. D5 v2 n, @
' G2 X" I6 X8 Z5 Y# f+ h) T7 L3 n$ ^* U
// DeviceFinder Callback4 b6 o0 I& I$ V
class CDeviceFinderCallback4 P: z& T+ l! y% v: P' x" n% e. `. `
: public IUPnPDeviceFinderCallback) o' x9 v9 a/ N. B% {* ]! n2 G# t R
{2 K7 \. Q: M* d9 J" C A
public:* [) w, ?# N- t( K; w6 C& R, q& G
CDeviceFinderCallback(CUPnPImplWinServ& instance)6 x; W6 |6 d$ K1 D" n2 N
: m_instance( instance )
; u9 X/ U- z* I$ u6 x, S; a6 F { m_lRefCount = 0; }
( l1 e1 ]* j6 B, _/ F! v3 N1 l' z: q' m* o Q4 U+ E# ^$ i9 S$ d3 R
$ P9 @+ Q' e2 @3 M: Z( p9 `: s. g3 l
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);, z& w5 n: U n, t
STDMETHODIMP_(ULONG) AddRef();
6 h6 Q0 Z. e' i1 b" M STDMETHODIMP_(ULONG) Release();
# M; W# X1 w8 Z" `! a% |+ t0 M& a8 l/ y7 b+ n0 \# K
- H. c3 @$ D: x0 ~3 E0 p// implementation
f* {' U5 w2 ^+ _) N# e+ mprivate:
+ _( o/ L! k4 ~2 |( _ K- V0 p d HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);3 m" k- G5 O. Q% g# i
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);% R6 \& L1 O+ w; A4 v
HRESULT __stdcall SearchComplete(LONG nFindData);4 @- [; R/ G. C7 s0 L( G* k
$ G+ Q3 Z- U& w
: ^3 H+ F% v' aprivate:: E4 A& x+ ~* p& v' H
CUPnPImplWinServ& m_instance;
) Q6 J- l P. ?$ W- z- R0 p LONG m_lRefCount;
* y8 J0 b! a6 _" f};+ _& i" J$ s( N" Q, i" E
( v6 y: f2 s: @; d% Y
8 j* e) ^2 R+ b( w( M4 W// Service Callback 6 L' n+ ?9 i# t" i2 M1 @% z7 R
class CServiceCallback/ I& d4 W' D4 C, q, B8 E5 Y
: public IUPnPServiceCallback* `# F$ ~2 A8 O5 T7 [ d+ g
{
' W' y* z1 R+ w, i$ X" tpublic:( u1 m4 j* G2 v/ B/ z) D s
CServiceCallback(CUPnPImplWinServ& instance)1 H( |! i( Z3 Q$ t Y. v
: m_instance( instance )
$ r2 W, m* b& ^; Z2 L3 w" {$ r0 u0 @9 j { m_lRefCount = 0; }
& H2 H' @ {+ Q" x2 S& { + ~% p! i+ n, f9 g: J
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
$ m8 `1 K; X! P4 P8 n+ Z) } STDMETHODIMP_(ULONG) AddRef();' }& j+ a1 E( u( Z2 I+ b( v8 Z
STDMETHODIMP_(ULONG) Release();
: c2 Y3 f8 O- g X
$ h+ [- l6 N* z, G: d' j( N& e& l6 M' x G8 f) \
// implementation$ F3 [' ]6 s# P5 S$ x" A( S- i
private:/ r% o& o7 ~* u0 n, H
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
6 S! K. D5 W# j+ N; W HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
8 h A" J8 e% ]. V# n
0 z+ `4 Z( y. C
: G* L7 ]" w, l0 ]# `' cprivate:# \8 O1 H) V" L% B) }
CUPnPImplWinServ& m_instance;" ~2 @+ f$ n6 ]0 r5 {" `* a
LONG m_lRefCount;& g l, N# o# s, Z/ k
};
/ S2 S+ @4 \* C" x# B# Q9 g! D
& N7 v" K0 z# _) }! v/ ~
4 e) }6 `0 x9 d* Q7 M; [0 h% G/////////////////////////////////////////////////
) A. K( {( o- L& L( l. k7 F- R4 `) t: R9 N! ~: k: c2 u
8 ]0 t2 C3 A p( F' t- P使用时只需要使用抽象类的接口。
) T$ P5 v( X4 v7 ]. K) OCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
$ b* U1 U' c3 H- P1 L7 C" \4 Z! ?' }* H2 HCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
+ ?# X6 u5 u) @: rCUPnPImpl::StopAsyncFind停止设备查找.* L, I8 ]+ g% B% e
CUPnPImpl::DeletePorts删除端口映射. |
|