|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
. w' ]4 f0 S, s$ V! g0 Y' d$ w( y% o9 Y2 \" ~1 A
( h# t& `: r Y
///////////////////////////////////////////
" j: @, W( O; k) [ u3 l% Z4 W//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
, u3 t, l7 J, h) }( Q0 D+ u/ _3 ]* e; [) }* ]+ ~
& O# t( m4 L$ N) \9 d7 n3 {
#pragma once
4 ~. `/ P- k( ^3 w9 f8 q- o) F#include <exception>
2 |4 `* G* J: j& d1 J1 d& w+ Y6 X/ N. o* V1 x2 M
: v; W m; O) F# _( s) T! H9 _$ J enum TRISTATE{; ^ O- {& j- Z! X _; I
TRIS_FALSE,
1 d! m5 ]2 i1 i5 Y0 _" ]' p# } TRIS_UNKNOWN,
2 h- A# }% P% X9 B TRIS_TRUE+ K4 U5 T ~. K' z. g" Z( u7 e
};
! Q$ D0 q% d) `% ^1 y0 {/ i+ M( @& d
# V3 u j. F' Y6 X6 c
enum UPNP_IMPLEMENTATION{2 Q& z* H: k# _1 Q9 ]# C: `. k
UPNP_IMPL_WINDOWSERVICE = 0,
( b+ z3 Q& w( y9 |& I UPNP_IMPL_MINIUPNPLIB,
- _$ M; g4 E% Q, L7 d& q UPNP_IMPL_NONE /*last*/( ?$ V4 c' E- R0 E) Y
};( t$ [8 z: M, ^; j" u
4 ~( `2 }+ |# V, Y- O
) `: n" A6 E5 A) ~6 j- K i1 o( D& P+ E) ^+ ^$ U! H4 {& o: g
( ~$ r, @8 R7 g. \) ?
class CUPnPImpl& e: D7 V( m) I( ]+ z
{
1 ~8 L% y# g+ G: [% Apublic:& A; x7 v! q* R9 ^2 |! B- P& P# Z8 n
CUPnPImpl();9 X, R2 _! Q$ M' v, b9 a8 o0 m
virtual ~CUPnPImpl();7 z( F+ l# N# D3 ]
struct UPnPError : std::exception {};
. ~' G/ ~; |; P enum {
, P/ J% y% B A& Q% f7 Y E6 [- W( R UPNP_OK,
4 f, o" L6 Y9 h( h- i5 p4 n UPNP_FAILED,) [" J5 C- Q2 }. t/ I% N) @; C
UPNP_TIMEOUT$ O# S9 f6 B0 u" I
};
1 c* a9 Q+ s' [9 _. m& c
* a$ }. V& M4 k6 R; n: Q n, ^8 w- N6 N
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
1 o, H5 r5 h; [+ K virtual bool CheckAndRefresh() = 0;
' w* h4 o2 ~2 G; c. Z2 z virtual void StopAsyncFind() = 0;4 {8 w7 x b1 e: m
virtual void DeletePorts() = 0;
: @5 W! z. ]+ o, M6 F virtual bool IsReady() = 0;
. D. ~* @6 `3 o2 I) M virtual int GetImplementationID() = 0;& w' u: v5 W2 P& B! a/ b4 x
0 r' z3 E1 J9 X { void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
- z: c- n/ p6 F8 }0 L' N. A7 g9 U7 q; o( D3 G
- G. L0 H+ H- `2 c8 }) z
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
5 C5 `" |6 U( p$ \2 W8 V% k! x5 c+ ]) L TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }/ v% u7 T1 V" j7 t) y
uint16 GetUsedTCPPort() { return m_nTCPPort; }
i1 a6 M7 L" T4 z uint16 GetUsedUDPPort() { return m_nUDPPort; }
( E: [: o. g& b1 Z8 U, R; ~0 _
7 N& z$ a% K8 Y R
( g+ a, f7 [% q) v, p// Implementation
9 j# \5 H) O5 V' {' Qprotected:/ R. E6 v- ?% p7 K
volatile TRISTATE m_bUPnPPortsForwarded;
6 R6 k* W! J' }' q' N9 r9 X void SendResultMessage();0 r" ~, _3 w% E* v
uint16 m_nUDPPort;2 G; {" X$ k# j0 @2 ]5 l- V$ N
uint16 m_nTCPPort;
8 W7 V) t6 p3 R* d4 Y8 v uint16 m_nTCPWebPort;
# G6 W, ?: S" x bool m_bCheckAndRefresh;
( U+ \8 G$ V- K0 Z& W4 M! {8 M! m5 o) u! g P+ u0 o/ V* w
& o7 l# k5 }/ Z! {; M) r/ G/ }
private:6 M' m4 }/ P }) G- o$ a3 H- v% [
HWND m_hResultMessageWindow;/ n* I- d& R& z( l- U$ ?! N
UINT m_nResultMessageID;
7 e, P) C5 `7 |2 i: A6 P: {: f. Z
* Z, ^9 K) \+ O# Y* Y' [9 k% @& X5 v$ c0 I2 v* V( a
};, L' V( ?/ }4 I# y( u# O3 W
+ w N3 s u1 Z
% Q( c- W, `& ]
// Dummy Implementation to be used when no other implementation is available
. c" R+ K; ]6 pclass CUPnPImplNone: public CUPnPImpl
1 r0 E7 Q0 U" v$ I" F* o( ~" F{7 o9 n% q. `! _/ P$ k5 M- b
public:
% ^1 F' @5 n7 o& d* |0 I4 j virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
9 F8 J; e3 a$ u virtual bool CheckAndRefresh() { return false; }
5 g H% d! N( }+ O; N virtual void StopAsyncFind() { }
' k9 ~1 ], T8 ]" ]2 p, Q virtual void DeletePorts() { }4 Z& p2 b1 S j3 s3 O) A
virtual bool IsReady() { return false; }
R5 m) u8 o9 N virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
( _# u6 N6 H+ _3 l/ G0 t};2 H! @+ o5 A9 m! q. r9 t/ f3 Z
' j! i3 c w* ]) i) A
9 M! p9 T$ o( a& ?/ ?
/////////////////////////////////////
0 P0 S: t4 t6 k! q" q+ y* p% Y//下面是使用windows操作系统自带的UPNP功能的子类7 [* n2 _. g; P: f
! T- h5 |% c/ a: @" Q9 R. Z& b5 z2 u1 M
, Y( W) k6 e4 d+ i3 H#pragma once. F$ A( m" ]1 {1 k
#pragma warning( disable: 4355 )
; u, y8 {5 Z; \ c1 C" s1 r) N" Z
' n/ o" [8 J, x0 Z" ~8 J7 ^1 T4 d$ m- M V; s8 z
#include "UPnPImpl.h"
x- r4 a0 O4 g, v3 Z#include <upnp.h>
) b- a$ U Q1 i#include <iphlpapi.h>
: O9 p7 \5 o1 N5 |6 T" E#include <comdef.h>7 Z+ O9 A: \" r( P
#include <winsvc.h>2 ]! b) g2 S+ B5 p; j. a
. f7 ^1 D" L- O* L# W' O4 L s. c7 p
#include <vector> M' P; ~3 Z( g( ], o1 ?% P
#include <exception>" r1 B7 Y7 q( a
#include <functional>$ g6 {8 i2 q$ }: c% b8 C
4 [1 `9 B& \( q6 n) H1 n& c& i2 o' Z/ d' e
- w# R: B* J) J! `+ w/ ?" P4 {+ H
, l; _% h7 a6 j
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
, Q0 v/ t8 y; e4 k, ]. Ltypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
8 A) I, y- ^% d F* S3 W* Etypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;' E$ [1 C# Y# E: J( C6 v; k
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;$ H! r8 W1 ]4 e2 o7 d. q3 H+ i. r
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
' v/ m& ^2 E2 Z% I/ a0 N0 L6 {typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
5 I1 R# o7 n# s0 i7 Wtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;" Y- w) t1 A8 ]
& Y# r1 o* G/ O* R# Y
J1 d3 x- C% [
typedef DWORD (WINAPI* TGetBestInterface) (
( T5 ]; h' m. [3 W IPAddr dwDestAddr,% U' B D+ G. }# g
PDWORD pdwBestIfIndex" t! ?" G. Y2 V. \: W
);' T' @$ [* V, ~5 ]% O3 }- n0 T5 T
& Y/ j0 N. l( p4 O
( Y2 U; _% Z3 V) `$ btypedef DWORD (WINAPI* TGetIpAddrTable) ($ f) u/ E' j! s
PMIB_IPADDRTABLE pIpAddrTable,% ~ L7 q+ I, q( O% k6 @: g# D
PULONG pdwSize,
& w' i7 {$ V* J W9 d, B) C) b! s- S BOOL bOrder
. ^5 `8 N7 L) M);' N- @" Y. b( E4 E3 v1 _ P
( ]7 _& f$ D/ l6 u5 q/ Z) h: ^+ Q7 x0 I% |9 H, @
typedef DWORD (WINAPI* TGetIfEntry) (: c/ |% d( V l) t7 Z
PMIB_IFROW pIfRow
/ T, c9 e3 X* ]4 S% M7 S: U);7 U2 [# q. ~, ^
8 {; p; B, n# ^# k
2 B) P' _6 L4 `/ c. y& b& y1 }2 KCString translateUPnPResult(HRESULT hr);; F6 {7 \ Y1 B2 u
HRESULT UPnPMessage(HRESULT hr);' R! P6 N- Z" B: d" c
( ]) f+ o+ X" V1 n! r$ `8 e; J) n
: W# G! K1 p" g# ?1 \% J& Fclass CUPnPImplWinServ: public CUPnPImpl
7 Q# q- q+ c2 T( {4 t7 Y% C% |% X{
+ b8 b0 Z& v$ ?6 ?1 g Y8 ] friend class CDeviceFinderCallback;
& q/ A7 ]+ w* u) {& L n/ C" D" v friend class CServiceCallback;) H9 z- l5 q! `# c% s& |
// Construction- P8 x. ~- Y/ s% m1 W9 S
public:
6 X6 X: t- H6 N% Z virtual ~CUPnPImplWinServ();
% j/ v2 ]- {& |) ~2 E" z CUPnPImplWinServ();
e- Q6 a2 i! Q7 E7 p" f
1 G: [# y! Z9 G9 F) o+ ^. a" R
/ S" m' t$ A* x# M% k virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }5 W! i; ^; j+ q$ O: S- S
virtual void StopAsyncFind();
1 e- a1 |% ~9 x0 b4 q0 p virtual void DeletePorts();
" ]6 U6 `$ R# f) U, K+ o" s# P6 Q virtual bool IsReady();# B# o2 B: F3 ]4 ~
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }+ X) T: t$ K0 Y: q" ~# J" H
7 s& r. y% ^8 m: O2 H2 U& h ]/ n, U, [
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
- G" b- Y% F) h: N. L: W // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
; M5 }2 H6 p* V; \' `+ ] virtual bool CheckAndRefresh() { return false; };% K: G; U' e/ P' X" u ?. {7 i
3 ^1 o8 {5 I n7 l
6 M% o4 j/ q: r* t; n6 _' T
protected:
, C* p" n/ ^8 |) G( n2 j# T% E void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
# g' L. o) ~5 \1 p/ N: P* P! Q void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
5 {* O3 M9 w. [7 o1 H void RemoveDevice(CComBSTR bsUDN);
9 M. [8 w8 @# F. @7 a: J bool OnSearchComplete(); {1 r1 M2 `) e. h
void Init();
2 g+ Z9 d. k+ ~6 Z2 z
) v) D. v: Y* W. P. V5 i! j0 C! g9 K4 ^- I# h% |
inline bool IsAsyncFindRunning() # E7 _5 H1 W5 E: {
{! _+ C7 e4 H& Q q$ A8 s$ P# v
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
m4 e% {2 \4 B' y) Q j8 m {
/ j2 `" M6 L4 P m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );1 c T( i h8 h! N' n
m_bAsyncFindRunning = false;
: \. H5 d: v. l4 |# F9 v5 E2 t }7 E' a: u( D: f) u( ] V
MSG msg;. M+ n/ N! N$ `0 n, Q% g
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ): A% a! q4 l- v3 D
{
2 m3 @ ~5 E2 U: X2 F o TranslateMessage( &msg );0 A$ A* u3 L9 M! j. ~
DispatchMessage( &msg );- O# ^1 h7 }0 p4 e
}
: u6 D. {. P4 D return m_bAsyncFindRunning;; _3 Z* V/ v3 {7 [8 a+ }3 m
}1 Q6 t$ U+ `3 o
# |, B) ]+ J) M, [
! u4 f+ t' S! h2 O, Q
TRISTATE m_bUPnPDeviceConnected;
1 V* Y2 S4 N j- g. x4 \7 x9 T4 O6 r o- C4 h) P. A6 _
. I. [$ Z! V* R( v) y& Y
// Implementation
7 M% `1 K6 a! S- t // API functions
& @+ {0 f* |. B2 c SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);7 |# j/ f( W. p0 N. ]
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
. ]+ ~8 @7 G% ?8 N8 l BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);9 O4 v& ~4 s. k% h
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
c* w: Q$ m- d5 `$ `- ]- C BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);/ }3 r( E& X1 z; B/ t6 K- B4 {
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);. I2 T( w. q' }' V4 h6 f$ v" i0 k' j
; P2 N" l) K# n; o
) T6 P9 H% _: b# D7 [ TGetBestInterface m_pfGetBestInterface;8 E8 g, }- i* i4 `: r: s2 }
TGetIpAddrTable m_pfGetIpAddrTable;
4 F# g) m* H4 ? \6 H TGetIfEntry m_pfGetIfEntry;
' t! E# Q/ M4 `! H3 W
) k; D! W6 n$ m: B+ v: J
7 ?$ i0 A; ^% p5 u+ D& \" ^) { static FinderPointer CreateFinderInstance();
: C5 N4 w8 q; F6 e( u0 e( R struct FindDevice : std::unary_function< DevicePointer, bool >
# Y8 J- M+ ?# U {
6 B" l- q5 c% r5 J4 t, ^ FindDevice(const CComBSTR& udn) : m_udn( udn ) {}+ X) o @- O1 x4 ~
result_type operator()(argument_type device) const
/ B; y3 ^1 A+ } {$ S' f5 {# z% x
CComBSTR deviceName;
4 g: x) H, @( o& I) M4 { HRESULT hr = device->get_UniqueDeviceName( &deviceName );8 O9 u y% O( m' y) I
; L& \. m# t: v# l" Z: [( H
: B7 s h% j+ \$ N b8 ?7 `
if ( FAILED( hr ) )1 K; o! ~# Q- C& F: Z' d
return UPnPMessage( hr ), false;7 t& l& a7 f% {& n2 L
' v- S/ o: k! K; W9 c4 R* k: v0 Y C- F2 F( K
return wcscmp( deviceName.m_str, m_udn ) == 0;. B. f8 V2 N; i6 a- U
}6 k' |. ~0 e: a6 t$ M: |$ j8 t
CComBSTR m_udn;
! i0 Q: A6 u: S. ~3 u };
% E. l( q5 n+ U0 R& K 8 E; }; f9 }0 Y: H: f
void ProcessAsyncFind(CComBSTR bsSearchType);
. P/ q* k [2 f HRESULT GetDeviceServices(DevicePointer pDevice);3 d3 g* W/ B% n) Z" x9 P) l
void StartPortMapping();9 C+ ] ~0 b, V" K0 y. m9 ]
HRESULT MapPort(const ServicePointer& service);
5 x- Q9 N3 k3 i) ~ void DeleteExistingPortMappings(ServicePointer pService);
& j1 _+ M) |( E9 e! M void CreatePortMappings(ServicePointer pService);
" P& }' M1 A) m- s }4 _ HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
) f3 [7 Y1 v8 \( G HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
' N/ m; C/ \, h8 V: y LPCTSTR pszInArgString, CString& strResult);
0 I7 R1 \8 D- t0 [$ b2 a# Q void StopUPnPService();, X& J' u" j2 L0 f' e& g* S) w
3 l8 s1 D5 m$ t9 e
( h6 I4 X# e$ W# Y% L& B" m7 B // Utility functions4 w' V1 o, K, U) t) ]! @
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
- ]4 V) H& a% D, \8 `' h INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
7 z }+ e+ e# j INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);3 o& |, R% `1 }7 s) g: a
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);2 u( u# j" L9 H% c d6 p& `( y
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
: P- h5 t+ H, P4 a HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);* m; W1 _; Z9 [; B" A
CString GetLocalRoutableIP(ServicePointer pService);
! t- X' A1 o8 S% I7 p3 D% s! _3 D- A
0 x" H* X" K) S! J g5 S7 [5 i, n// Private members
3 t. h( O9 O% ^3 p k* eprivate:4 H7 ~3 D1 v& O9 Z: P7 B+ R
DWORD m_tLastEvent; // When the last event was received?& g- d8 d7 R# k
std::vector< DevicePointer > m_pDevices;
0 f$ O5 R% Y! p std::vector< ServicePointer > m_pServices;
. I- f$ G& d G. d FinderPointer m_pDeviceFinder;
. O5 @. \# m0 d- L9 K1 T DeviceFinderCallback m_pDeviceFinderCallback;9 l/ E8 ]" @* F5 }# H( u5 ^; w
ServiceCallback m_pServiceCallback;
- h: J; }6 E- B8 G+ T5 Y. [( s* ?- ^; i* ]" a$ j1 W3 L6 v: C2 O9 ~& e3 Q
% x$ n4 [5 K+ f& W1 V6 W LONG m_nAsyncFindHandle;3 |% {1 w" C, w# o8 |
bool m_bCOM;
+ E2 s% u* a) Y8 t bool m_bPortIsFree;
8 l# }5 E( W5 b; E- _* s3 U CString m_sLocalIP;8 n# I# ~( G1 }( j
CString m_sExternalIP;
! C( j2 X3 X* k# L2 L bool m_bADSL; // Is the device ADSL?
. Z- G# m" C( \7 T8 ]9 N5 _$ e) V bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
; i: o5 c+ ]- B" E: Z+ P bool m_bInited;
7 U9 n2 v4 m( { bool m_bAsyncFindRunning;/ M6 ]: Y9 `- a9 s% Z
HMODULE m_hADVAPI32_DLL;" X* `9 S0 A. O% n2 ~( F2 e
HMODULE m_hIPHLPAPI_DLL;- e% a% d& v$ E6 x" W% V5 P# n9 Y
bool m_bSecondTry;
6 x, r0 e3 X2 ^; g0 k bool m_bServiceStartedByEmule;
% } I9 i0 T9 E4 o bool m_bDisableWANIPSetup;
- X& _( }7 {: Q9 O bool m_bDisableWANPPPSetup;
' C5 x2 W H) U8 s7 T
+ p3 H3 X4 T7 [2 Q1 v! M; \& l ~3 t, A. s7 K% O4 l+ j, S
};
6 n2 C, y2 z: u, Q9 G% t/ c9 V, Q! w2 V6 n5 v% t
7 y$ w) ]* W/ ]" F4 D
// DeviceFinder Callback% K `5 y5 I2 N. J% B" @
class CDeviceFinderCallback$ V2 L( \$ [( s* {' P) _7 C
: public IUPnPDeviceFinderCallback
/ B" x) R! V1 V: D f- |! [, g0 S{
+ P. O: [( F2 U4 @& u- n8 |( Q$ Qpublic:" q% f+ ~) m: r3 n+ K
CDeviceFinderCallback(CUPnPImplWinServ& instance)& v3 P! u, K; d
: m_instance( instance )
9 [6 Y% M( Z, h. v9 G { m_lRefCount = 0; }
/ u/ Q& @/ e' ]* i; e6 C, O% S+ k/ l! m8 [* L
. G( ?3 @ o% `' p- g1 K" I/ E$ ` STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);1 V- k6 V: f; T% J% c
STDMETHODIMP_(ULONG) AddRef();) u; h9 M$ {+ X. h$ U/ ?) [ y
STDMETHODIMP_(ULONG) Release();
/ S8 l, n' j. b4 Y7 C5 ?
% ?! {7 D5 A m) }: p# g' F( g; T/ s( V7 V
// implementation
( N }; y j& S; ~" {' Xprivate:" s/ k2 _, }* m4 u) T0 V( B9 M' g
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);" ]+ Z" p) q# b- a! ?' g% b
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
7 i* C$ |7 [: t" d6 x8 T4 Y HRESULT __stdcall SearchComplete(LONG nFindData);
, M, j, Z( m. \0 H4 n" }" y8 }
: z. J: o" p6 N/ O. t! ~* V1 p7 h& \3 x0 ]7 h- R) e
private:
) c4 b% j' z6 d# T# ]# Q6 G$ B/ t) z CUPnPImplWinServ& m_instance;/ P* H; V! W, Q; V4 c1 b$ q5 k
LONG m_lRefCount;
& p% u$ j) n* ~# `3 N" C};0 n. x6 K( c% w' I! B
/ w/ y1 o: b* ~ l; G. d
: T9 R$ k0 b$ O9 D m// Service Callback # a D0 w$ s$ R8 N6 l7 ]
class CServiceCallback' K' i3 h5 c$ l0 D7 N0 u0 ]
: public IUPnPServiceCallback
$ z% J' A! O, G F8 v0 g{, D0 ?. O: d% B; }3 v5 }7 M
public:
; \; J1 g' J1 k CServiceCallback(CUPnPImplWinServ& instance)
F7 @" {9 R9 }5 P$ @8 P : m_instance( instance )" ?; U0 X1 H# ~4 J% Y; i
{ m_lRefCount = 0; }( H2 J v( r, S% D# d
' F! Q6 v( x) f2 f0 q$ y STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
( J6 L/ S5 Y8 m' A# Q, b STDMETHODIMP_(ULONG) AddRef();: A; l! N% e( O2 u) [# I
STDMETHODIMP_(ULONG) Release();& R6 I$ R+ d8 ?% b
2 T( ?! b$ s* O7 H; q1 h
6 l7 o7 r0 M8 D" y// implementation
' K% D+ d( u8 W7 Iprivate:
# |* c4 a5 m/ J3 I& N; v HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);1 _) d$ I& C8 f$ Q( i: `4 N
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);' b% Q' Y2 [2 }% M2 E3 Y
) K+ ]0 h% w# F1 g( P1 H' D5 c, H
7 Y8 A/ I! p3 w7 S; Q, @5 z
private:
! f! u; p" m6 _" r0 ~. T4 g CUPnPImplWinServ& m_instance;
2 W: a" r$ v! g% l: F$ c& R8 n6 s6 d LONG m_lRefCount;0 o) y6 ]4 `9 j9 G0 d
};
2 n- C2 L* D4 u) u0 @% p8 ^( E
; t; b! `7 P9 C8 B/ _* b R
9 B& W- H, B: b2 }- S4 O. k/////////////////////////////////////////////////) X/ B3 F3 Q) Q$ _8 q1 k; `7 s
7 e) F3 f2 U3 g I
. z! m2 F8 p3 Y, C使用时只需要使用抽象类的接口。
( b; a4 s7 A5 R* W' P- `9 rCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID. m e. a+ ]+ z$ {
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.% `1 } E( [8 U- J+ z
CUPnPImpl::StopAsyncFind停止设备查找.
& g0 D& ]' K9 b/ @# uCUPnPImpl::DeletePorts删除端口映射. |
|