|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,* [* U7 j |3 h. ^3 b& G
! n1 b3 s5 C6 Q, `- g7 i; W
# ]& P% s% n( ~# W% J///////////////////////////////////////////
! j' \" r x- a+ {: u//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.+ b+ P+ @5 Q2 c+ c% O) t2 b# w3 V
; x6 s n1 P0 e# h9 L
# Q! K0 y+ s" m. I
#pragma once6 E2 w& d6 g3 q5 ?+ m: D) V7 ^8 J: y- }
#include <exception>
' U4 K( X: V: d" U
! p6 q& G: o' Y. H/ J- B. m& c7 Y# `
7 a s% y# O: \/ R# t enum TRISTATE{
0 x, h' u$ _% E6 `) I7 S* c TRIS_FALSE,
# [( `% D. t' N$ y( t TRIS_UNKNOWN,, f' [8 Y* m- G! [9 }
TRIS_TRUE" }, s' r0 {% H( O% U+ l
};2 V2 u% Q* s( |& j0 z* \
$ q& C8 ^) q$ t7 R6 B( U1 F3 x X" _* O n* |! ~- m+ `
enum UPNP_IMPLEMENTATION{
3 t* | N# M5 n3 ]6 R$ c+ j6 H8 { UPNP_IMPL_WINDOWSERVICE = 0,% V% R. Q% G- g
UPNP_IMPL_MINIUPNPLIB,
# r9 c$ ] i' g/ M1 W n8 Q UPNP_IMPL_NONE /*last*/4 m. t) R! l. ?' ~% e) }/ }
};( x; u# y: v# d2 ]) b: {# O9 T
4 j c8 d: o: F/ w8 J# m" a8 t
! W" G- @8 o, m0 Z; L: ?! ?) J
* ]7 d2 R! r1 R
) c% M0 }8 [7 d) Tclass CUPnPImpl& Z0 q9 ?3 N- {1 r% `* K4 y
{
$ ?0 s) C9 Y4 ?/ V- l4 O$ _. ] dpublic:
3 B; D% g) V \1 R* O CUPnPImpl();
; ~% Y3 [! I9 W5 |; X3 D virtual ~CUPnPImpl();/ ^2 c B9 [ R6 W, K6 h- H
struct UPnPError : std::exception {};
; Z6 Z, S/ T6 f0 R" {0 \ enum {# `4 M* M- e% V0 Z( }
UPNP_OK,
: c8 G l8 \3 l ~6 z7 a UPNP_FAILED,* P" H2 Z0 p( \! S! F
UPNP_TIMEOUT9 }+ o0 A6 m) m" G2 S$ b7 z2 u
}; Q8 x, @2 K% M7 x6 ~" s% H
* g/ W: U6 d( L; D
% t7 N: X( y4 c e0 O virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
8 s f+ n. m+ x7 N V5 G$ H virtual bool CheckAndRefresh() = 0;
& z5 ^/ f' }' G& U" b virtual void StopAsyncFind() = 0;
0 k9 f/ z- r9 S2 t& l' ` virtual void DeletePorts() = 0;
t- }0 i; {2 n virtual bool IsReady() = 0;$ |2 N2 Q( _% y, s" E0 c
virtual int GetImplementationID() = 0;
( l2 m' l D8 c7 B' ` 1 y: g8 o$ |! U
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping7 K) R9 h8 ]8 {- I
% A& |! ?- `5 `1 k ~' h N- C8 q* }
2 A# f; a9 r/ N9 K
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
' B" N: @1 y7 c1 | TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }# \% F" p }9 O% p& y
uint16 GetUsedTCPPort() { return m_nTCPPort; }* O) }/ `1 z, Q1 S
uint16 GetUsedUDPPort() { return m_nUDPPort; }
9 Y( F* s1 v* _) M% r) L" I \5 B o; k0 f
# \3 l, h! f! H, d% _
// Implementation1 L; l, u8 L* L
protected:1 s) |2 k" e9 P8 Y& e1 m/ D' Q2 _
volatile TRISTATE m_bUPnPPortsForwarded;3 r2 p- g9 m( D7 ~
void SendResultMessage();
( N a& j& C! s$ P uint16 m_nUDPPort;" F6 J5 k5 X! g, p. x$ G" u4 |
uint16 m_nTCPPort;1 n ?) H, ~* |
uint16 m_nTCPWebPort;& B- P, [6 g6 S0 A# q; @
bool m_bCheckAndRefresh;
+ T/ }- Q: X8 `0 @9 [" O) V
% j' u7 W4 p# x; |% {8 F
( q, F. G% }0 u6 D" J' yprivate:3 F- m. D& P8 z! {1 n5 z
HWND m_hResultMessageWindow;
4 z/ A% N. D9 z7 r) X UINT m_nResultMessageID;/ p5 a8 \+ _* j/ R2 M5 f$ O
6 A9 i# w2 e Y; R7 V- D& x, _! \( G- P; d
3 e5 I, H7 u% M% V( U$ y
};5 V: r6 v9 Y+ K! p- I/ A* R
( q z/ c4 Z" W
' J* z+ e2 o' E% p/ e! l" h0 w// Dummy Implementation to be used when no other implementation is available# ]0 J+ N) l% i# D
class CUPnPImplNone: public CUPnPImpl9 x7 M5 A) }. r5 F/ j- W
{
3 K( [- k) P' I& ^% upublic:
- X0 n9 r' L) d2 |. x& q virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
3 u5 H3 T4 x' w5 v! m H5 O virtual bool CheckAndRefresh() { return false; }
) v$ V- c: p0 k$ B) \6 P; C virtual void StopAsyncFind() { }
, `0 u& V9 p1 h; \8 F virtual void DeletePorts() { } e4 a9 l s& C% j% s) S, Y
virtual bool IsReady() { return false; }
* _; z& {6 a* S! ] virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
' t! S+ W) w: d};9 t: G& i; a. x& ~, X% g: q. Y
! t' Y3 J( J' V0 Q; Z- h6 |' f
8 [2 l% g# S, e. z: ]/////////////////////////////////////
! T" ?# [: ~4 m$ }; `//下面是使用windows操作系统自带的UPNP功能的子类
. |0 T* F& G9 [5 @3 q4 v" J7 X; I- y3 U1 ?1 `2 _2 e
J+ I5 o& I7 ]8 @#pragma once
. f# v4 w0 r2 L( M/ i3 R#pragma warning( disable: 4355 ), L% d- F$ j, Q6 Q2 T2 A- y& S
+ C4 M" Q4 ~ ]
6 R* v L" U; ~+ l6 F/ R. x* }+ |0 d#include "UPnPImpl.h"2 D) ]) v( d3 X+ t( n/ j: g
#include <upnp.h>
; v6 o0 C2 b. F$ o( s9 K#include <iphlpapi.h>* P) T; j! \( e" j p
#include <comdef.h>
4 {& u8 x% T0 t#include <winsvc.h>
& P2 |4 N# J9 |* d- m8 k& X+ f# f5 d4 s6 F! a1 N5 W
. z2 n8 Z- Y: q5 Q! i1 T9 H#include <vector>
6 `& A6 L ]: S#include <exception>
$ j7 M( I" k$ t' b! e- d8 w+ ]#include <functional>; x. a" z# q' |" O
# C! u$ t( ?8 N: n! W1 {
2 ^0 ?, }2 H% ^2 K
6 ]$ T0 w2 I$ L1 l. u! F
! W* B: [" m, u; ?7 btypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;( U/ v" [- I# `. N+ E
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
' [0 Z9 S, M8 B5 |typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
% p/ N8 \3 E# J3 etypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;6 W) F' h! m3 i# Z; r
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;0 {3 J. A' ?7 P) n/ N; p, P' n, U
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
: b% c P" g, R7 m" B* ?, Ntypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
5 k8 z( Q- \+ n# @9 r( }0 e+ _( c L& ~% ~+ r7 u+ y
! G$ r# o9 z4 |
typedef DWORD (WINAPI* TGetBestInterface) (
. U# \5 r# c% o( M$ f IPAddr dwDestAddr,
( ^# g) K( K. R& G% M" I4 @- x PDWORD pdwBestIfIndex! w& K8 C5 r" c/ `; `0 j" e
);9 b0 K" J7 @ x$ r$ R* F
4 n. P4 Y4 r2 a7 T( E
3 `4 @: R7 \) C: }4 H& K$ Y6 o% ^typedef DWORD (WINAPI* TGetIpAddrTable) (
7 L& P4 W# \1 \# `5 U3 o PMIB_IPADDRTABLE pIpAddrTable,
- R! ?9 M/ |1 `) \8 ]7 | PULONG pdwSize,
2 X# d9 b9 O& ^ BOOL bOrder& O$ Q) I& z* Y* A9 ?% p' O( J0 L
);
9 C" R0 N E) G* i1 U( S
" v4 e' ?$ a7 @& Z# n
# K% v( E7 C |6 I/ F# atypedef DWORD (WINAPI* TGetIfEntry) (6 u* {; n* ~0 i
PMIB_IFROW pIfRow
. f( L# }; P& Z: a2 Q& B);
9 P% e1 E/ m5 ^$ S, h L& N. @1 ~/ M b& [) G
4 D& |5 ^: y0 f/ Q" T4 |( PCString translateUPnPResult(HRESULT hr);# Z; Q' c1 a# I) m0 G, H; \
HRESULT UPnPMessage(HRESULT hr);
5 u* ]9 g/ j+ i! r1 E% [; `1 D, {5 U5 ^ Q
+ N# o. k, E/ |' R, z9 v# x, zclass CUPnPImplWinServ: public CUPnPImpl+ U8 s( u) |# Y/ X
{
+ p# R. b" S7 g+ ]: p; a friend class CDeviceFinderCallback;
& o& \; |4 U# i1 }/ ` friend class CServiceCallback;
' z# m6 F. B* B* C// Construction
% u* x0 {* n5 m s8 c9 kpublic:4 l% C1 Q2 A6 [9 P1 y
virtual ~CUPnPImplWinServ();+ T7 ]4 h9 r% ~
CUPnPImplWinServ();
* A* O$ x* N3 ~
7 S- N* y7 ~% C5 ~4 R' X
: U O# S5 M; ^- K$ Y4 A2 T virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
/ c# |. ] T4 H* b! C) P' P virtual void StopAsyncFind();
# X9 \0 }7 z' _& |. W virtual void DeletePorts();
. \* u; @) z- ~! s, k# v" t virtual bool IsReady();
9 L) _4 L4 [ P7 u- o# f2 M virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
- H" I: R& g+ }3 i1 J, `8 s& E3 w5 H7 Z/ i
6 p3 A( r4 V, B% d" ^7 k // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
' w( t' C6 U' z; R // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later2 @# q2 B O& V) }- l
virtual bool CheckAndRefresh() { return false; };6 s5 s( H( x8 @
, A. c4 c% B6 ]) r
7 d5 K8 \% O* w1 Yprotected:
! l; ? Z9 S: @5 q3 r9 \ void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry); h4 }! s; V& h1 e0 s
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
8 E Y8 u# v- ], [- |5 w- t void RemoveDevice(CComBSTR bsUDN);3 V) {; H- Y( r
bool OnSearchComplete();0 b/ a6 Z0 K* X, K: i
void Init();
5 d7 Z" s# U8 V; E* c
- F/ X3 Q }$ p0 V" X( x% E) r5 n- [, {: J6 o# U: M
inline bool IsAsyncFindRunning() : _" i) h, p" B$ ?
{! k/ _' f) g) U9 c6 y
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
8 i, w" L/ W, d8 G* Q. m( Q- k {3 Q2 V" I( j, n6 n( n% D
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
8 F5 {' `4 Q$ s. X" { a3 M m_bAsyncFindRunning = false;
( ]) c# T6 D* q }
& B ^3 X, _' V9 H" ^* l( H7 b MSG msg;$ Q* `& P" U( e
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ). ^/ @, ]( E1 A4 O( o4 v
{
. g" |7 l, l1 t TranslateMessage( &msg );
3 ^( l$ L& s# u DispatchMessage( &msg );* p: _3 l, q. r. H( C+ |; @
}3 y6 ` t! t; Y% [9 a! I) p; L
return m_bAsyncFindRunning;
5 L9 o/ `# c& J$ y }
/ Z- i! X e" e8 m1 H6 e% Y& Z3 @! R v
% l3 w8 ~2 r5 ~5 [7 n
TRISTATE m_bUPnPDeviceConnected;, m$ [' v: I7 Y% Z
/ c( E' F9 [7 O4 k9 d" _, p$ A) X3 q. ?. Z2 s
// Implementation
7 w- x6 ~5 r- w // API functions# ~2 _, i3 S0 ~/ ?( ~* S$ u
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);" t+ r( F- N( b2 J4 d
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
- X2 h, v4 @/ q1 V* O( z BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
7 C5 x0 p$ @: ` BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);; D' a. U7 g3 p& v5 q3 T4 |% P7 B
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);! M" N8 P- Y& d/ I
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);' R3 x+ Z7 D' l1 ]
* u0 t0 [" Z9 `7 m
2 Q0 `- M: z" U# j TGetBestInterface m_pfGetBestInterface;
* y6 t/ d" ?5 M: z) w TGetIpAddrTable m_pfGetIpAddrTable;0 g4 l1 t8 H8 u" [
TGetIfEntry m_pfGetIfEntry;6 r. r, u/ d' ~
7 G& F" x$ }: r. Z* a# c8 h6 q0 E$ r
# n" K# P% v, h! u static FinderPointer CreateFinderInstance();# E1 Z# c' c9 N) W! [. U
struct FindDevice : std::unary_function< DevicePointer, bool >
K$ f: U1 f% C {
& k6 t, V; {' q" v( Y+ y7 _! K a FindDevice(const CComBSTR& udn) : m_udn( udn ) {}* C4 Q7 O. g V4 g! c& J
result_type operator()(argument_type device) const' f+ s3 z4 e8 f8 C
{
' P& I7 C3 E# C* C0 N' s7 v- j CComBSTR deviceName;
6 q! t' t; @9 N7 n9 a$ | HRESULT hr = device->get_UniqueDeviceName( &deviceName );
2 X* r: E2 X. W+ w. ?. `7 {# m2 V& p$ ^. _ o, v' D9 c
2 ]7 S: @- h6 G5 Z4 n3 d
if ( FAILED( hr ) )0 v6 w( w5 w( O: g2 T1 z
return UPnPMessage( hr ), false;
* {0 ~% d! i+ d" h7 v# C+ V7 E; F
0 N. S! @6 {: k" m9 ]' J6 L0 \2 }4 P. B5 w3 l
return wcscmp( deviceName.m_str, m_udn ) == 0;
; E2 O& Y$ g2 ^4 ?! t. }' \ }
6 @ C9 A [4 `; R- R R CComBSTR m_udn;
, f; U6 \' M. m7 \. K( S };
- [8 X Y, w+ D. E: \4 R+ ] 4 }0 ^$ T% w9 |& q
void ProcessAsyncFind(CComBSTR bsSearchType);' w, n4 a, c# D9 u1 y
HRESULT GetDeviceServices(DevicePointer pDevice);
: n8 A1 \* V c6 _) K' J void StartPortMapping();
. @) p P2 T" ]+ x4 B8 _ HRESULT MapPort(const ServicePointer& service);. T0 W1 R" d' Y u$ N* H4 A/ r: a+ h
void DeleteExistingPortMappings(ServicePointer pService);( e: A+ c9 j& d1 f0 Q1 r( i# H
void CreatePortMappings(ServicePointer pService);
$ G7 Q/ v3 }3 R% T1 H0 e; @/ D HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);- Z7 I |4 H1 ^* y! ~
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 3 l2 ^0 N2 \) t. K( `
LPCTSTR pszInArgString, CString& strResult);, L; ]6 G2 X/ N) R; }. h
void StopUPnPService();
0 k+ R) ?/ I3 z5 R5 d; C( o, R3 G) L3 Z' J
$ u/ t2 g% b. K& {# I. }& q( I // Utility functions
& u, M+ L1 d! m) Z HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);8 i: t5 z; O; ]! c! n
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
8 X4 w# z" [3 m4 q$ o; ^ INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
5 w- n+ f0 z* H8 G4 h, y void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);. W; w' W5 q6 n& \" e
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
! U) i1 C4 n1 F4 M HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
4 p( ` w. l' V- J0 F2 |! @3 f CString GetLocalRoutableIP(ServicePointer pService);" Y5 |, M8 e) L# Z; B+ ?
1 L3 F; f) ?6 p
+ h' o6 T1 l9 M3 f// Private members
0 d9 ]) H+ H) a, y: H# P, @' E& wprivate:
! l5 L3 n- _ w" e DWORD m_tLastEvent; // When the last event was received?
T0 H2 P0 `- v+ P std::vector< DevicePointer > m_pDevices;
, T/ l8 Q ^5 Y2 w* q* [ std::vector< ServicePointer > m_pServices;
$ i" A6 d, W t+ l& i' V8 V5 H FinderPointer m_pDeviceFinder;4 ^" h* n$ F, w3 I; ]
DeviceFinderCallback m_pDeviceFinderCallback;+ }3 Y _& w' b7 X$ Z* L
ServiceCallback m_pServiceCallback;
/ o% U c. U- {2 B1 d6 s) j% X% V! C2 u) _" U( i
9 S- D# ?4 o3 x" d4 b/ a( @" c
LONG m_nAsyncFindHandle;! G" {# R J% y5 N# D. n" S
bool m_bCOM;
, K: A7 D2 F- `( G/ Z: m* A/ y bool m_bPortIsFree;
9 F5 ?, Q& f1 I8 q CString m_sLocalIP;% v) ^2 c8 S d3 `' z% j
CString m_sExternalIP;
$ P/ f7 o. v& ~2 f' k bool m_bADSL; // Is the device ADSL?6 ^# ^9 B% s/ {- m9 u
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
9 k4 [: x" N; p, k: p% i bool m_bInited;
& h" h* T g9 ^5 m( E6 @6 N8 b2 K bool m_bAsyncFindRunning;
: n+ _7 R `( B/ V HMODULE m_hADVAPI32_DLL;" {( @$ c) ?( i/ B4 h' _' Z* U
HMODULE m_hIPHLPAPI_DLL;
+ d$ {: c: ?6 m [' W# D$ f& k0 u bool m_bSecondTry;
. ?/ o1 z: s4 ?( ~: p; K* E bool m_bServiceStartedByEmule;
1 } k6 c5 c/ U4 [: o" c bool m_bDisableWANIPSetup;, p& z# D& Z7 n G3 v7 \! i9 l
bool m_bDisableWANPPPSetup;! o) t9 T& g& i
! h! f/ J; b( T) a7 v. W: ]
( B C% [- d3 A. @) r7 P; `& m};( F) B1 X( y7 _, T7 J+ O: C6 u* T
0 R' m Q9 G" {9 Y4 x: I5 R
9 ~: j) O- j; m+ e9 g( {3 ]& Y// DeviceFinder Callback
; W- {! f0 D& S! vclass CDeviceFinderCallback
2 Y, \1 ?8 V$ q5 I. P : public IUPnPDeviceFinderCallback2 E% D8 @# \: N2 a" r: Y# I
{
7 a" Q$ ]6 ~: q6 Q# J: hpublic:
# b7 {9 ~3 N5 `4 } CDeviceFinderCallback(CUPnPImplWinServ& instance)
+ B& r4 Y0 g, Z+ K : m_instance( instance ) K0 V6 ?. @$ {" H# M$ _
{ m_lRefCount = 0; }' o% Y& a& s* c1 R6 E
6 n* _* j: h; _/ n H& K! ^! X: D Z2 H" e+ J8 ]6 y* Z
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);! F2 X }6 R5 D$ u0 h9 E/ k
STDMETHODIMP_(ULONG) AddRef(); \% ]3 z: z S- y R8 h3 z
STDMETHODIMP_(ULONG) Release();+ c6 T( Z' O8 t0 j
! v' u- t1 ]/ g: e a% V
1 O M+ n# Y1 v% z# h// implementation; h0 b3 ^8 T& b) f
private:
3 e( t. ?2 b/ x* K HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
: k$ W0 _: ~6 o! M% j6 i! B3 @ HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN); e0 @6 w. ]* T2 F# l
HRESULT __stdcall SearchComplete(LONG nFindData);) @+ [* b5 U, N& o9 J0 V& |/ |
; i( u4 T- L) w( |: z" e/ k" |
. @, r) J& W8 U& Y' S( Z% t; Tprivate:
* {: o$ U+ C# ]% c7 g7 a7 h CUPnPImplWinServ& m_instance;
% `* T: p- S+ w2 d! u1 V/ g LONG m_lRefCount;
' @# a- f( a5 W8 c% P- H};. @ f6 n, `: ~% O- s, `, x, p
* V& i- [$ L- k6 W f# _
. v% X2 z# J# {/ X" F' F. k
// Service Callback , l8 w% F# ?2 M
class CServiceCallback
. e: j5 L$ B; B' T : public IUPnPServiceCallback9 [- [: |* N/ v
{: r+ u- j" D; O3 v! k% j
public:
4 J0 @- B4 E6 i! |/ w; e CServiceCallback(CUPnPImplWinServ& instance)
7 W3 l- [) B5 f4 C! y8 i7 b : m_instance( instance )
3 `! H9 [% I- Q { m_lRefCount = 0; }7 \$ |5 {2 v6 e! G- S, O
; V; p" O, ^1 h2 _" W
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
: }3 P6 s" P- @* \+ t3 e+ z STDMETHODIMP_(ULONG) AddRef();; q7 g- {/ H4 w! E4 }% R/ i
STDMETHODIMP_(ULONG) Release();
% b1 u2 b' w: u9 Z4 R- e5 h; G) m' \ v h
% L" W* ]9 R) u8 j. j" P
// implementation
. J* n1 j8 ]$ L& ~5 sprivate:) E! i% b5 g6 q: w8 X
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);$ f$ Y# k/ L W% f6 P
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);" U; K( u2 k- _. ]0 ? W" }# T
8 u p2 @! v/ m) B& T1 q
, r( Z2 q0 O8 j! z9 [& dprivate:
7 X7 P5 _, ~4 n4 e( H CUPnPImplWinServ& m_instance;
) J$ G. o0 @2 n8 W LONG m_lRefCount;
+ `% U5 E, ]0 @4 ~7 H E};
3 q! ]+ h3 q5 U3 C" g
5 G) P% V# @& |0 y% a- ?
2 a8 |; }+ M& _9 _( ~1 b/////////////////////////////////////////////////
: _* J$ s' z/ I( q6 a5 z* B
) p/ K( G2 x4 t7 h x/ P1 n* p. P H; m
使用时只需要使用抽象类的接口。
~0 G: L1 w& E$ e. u1 b6 }* j) zCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
3 Y8 c' N1 ~, V4 }* {1 e4 SCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
, g1 [1 f$ o& S3 @ j, C) d8 bCUPnPImpl::StopAsyncFind停止设备查找. s. _0 p7 I+ n9 v+ ~2 T- U
CUPnPImpl::DeletePorts删除端口映射. |
|