|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
/ f3 M/ p b# V' Z, ^
( ` ^3 K% A* @+ C9 j
. K+ R; V9 |1 Y///////////////////////////////////////////7 ?! u' e, K. U3 J! A
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
- Z$ b* x& x$ o; u- F v0 M/ b$ T. h7 n; G
/ Q* e: W& r6 H; R
#pragma once
% o' f0 F- f2 r5 B# K C9 S3 T#include <exception>
3 {. u+ {0 l2 S# N2 _% B( {- Z: W% X. u
2 Y- e& p7 Q! n& X5 [" R
enum TRISTATE{
6 u+ ?" D L5 D9 y TRIS_FALSE,
; A. D5 v/ _6 n" y TRIS_UNKNOWN,
/ k6 C! [7 Y N, o. }1 W* o TRIS_TRUE' W+ j! |; J; F
};6 [1 `9 B) m9 f: V! \
% S$ ^+ x# \8 G5 V B! v9 j# q
& [. o8 Z$ e: V9 p4 @enum UPNP_IMPLEMENTATION{
) n* V% A- w$ N6 S UPNP_IMPL_WINDOWSERVICE = 0,( k- i( z) K& p
UPNP_IMPL_MINIUPNPLIB,
2 [$ \5 d) _* \7 e! t$ x: z) r$ k UPNP_IMPL_NONE /*last*/$ x! L; o1 [; K
};3 L0 b/ P) |( i q, x
- P! V+ Y1 n2 e( S
6 v+ v3 [+ n* @6 y7 V2 ~8 a
! A* H, L! u8 y4 y0 G1 L0 x3 {
; Z! C% a r4 {- {class CUPnPImpl2 t5 `/ V$ P% z5 l4 \3 R: O& F0 Z
{$ Y2 j7 }1 u/ H/ V" }6 l/ l
public:
! `& v. R, J: E U9 }8 k CUPnPImpl();
; Q. Y d. e: f \ virtual ~CUPnPImpl();9 ^) [* l# X1 K% T1 I7 x0 w
struct UPnPError : std::exception {};- d, d6 ], x, s9 _' @: _
enum {6 W% s d N/ t! W
UPNP_OK,# h s% }1 Q: C* E6 ^4 e( J% c
UPNP_FAILED,5 b' h6 z P- R( h
UPNP_TIMEOUT. A1 _% u0 u4 G: K5 E9 W5 `: r w- y
};$ _ a1 C0 d7 O8 a
* d! g9 R/ y" B; F+ a9 a* z: W6 p
" u; y, d5 r% X+ Q5 j' Q virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;: D0 V5 u f1 F ^8 t* P
virtual bool CheckAndRefresh() = 0;
/ b2 h6 R6 P2 m6 e+ n virtual void StopAsyncFind() = 0;+ e# m/ M6 p) o4 H( ~
virtual void DeletePorts() = 0;
' D0 r' \# d: D) e. B ]$ | virtual bool IsReady() = 0;0 N9 M; ~& [$ j2 M# k& a/ W
virtual int GetImplementationID() = 0;
" r6 \: E% k, c9 f5 q! A# \/ b% B # n2 v; Y( E+ |; ?! g$ q& O: ^$ f+ D
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping9 N, Z# L2 a. a: U
. c8 W+ {& B9 @+ p1 ~% \
1 d7 c5 Q$ T2 W8 p4 |$ H: Y: ~ void SetMessageOnResult(HWND hWindow, UINT nMessageID);
/ R# m/ X, `5 s( P- @7 H8 [ TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }+ v' P+ `/ m" }& x: b9 E6 ]4 Q
uint16 GetUsedTCPPort() { return m_nTCPPort; }$ Z5 `5 P) }# k3 T
uint16 GetUsedUDPPort() { return m_nUDPPort; } 6 U- S/ r3 |. R$ J* o. L
3 u+ y# i+ }5 g+ ~2 f9 R, U
% G' x+ k, Q- V1 R8 U3 z X2 }// Implementation$ B5 M/ c1 l/ ?3 V% \
protected:
9 h8 q* F# S1 t volatile TRISTATE m_bUPnPPortsForwarded;3 o H% f3 s% K, u+ ~) ^
void SendResultMessage();
9 j" o6 g) w/ n* {0 T uint16 m_nUDPPort;( P* t. _/ U: l' v
uint16 m_nTCPPort;
3 z- O, K2 l$ p" {7 } uint16 m_nTCPWebPort;
7 C2 e7 G# G3 J8 D% }: ~- s bool m_bCheckAndRefresh;
7 w' C% N* E) m7 y. C( M3 o
- u4 O+ r. f, v5 l. c
$ R# F1 a% n: F6 mprivate:
0 U. s0 n' S& W+ Z: Q8 { o T HWND m_hResultMessageWindow;8 I4 c) n; w; n; z. i" R6 L
UINT m_nResultMessageID;
6 n5 i4 q" |& @8 D' c4 u( ~+ }! Z A, U7 Y/ p2 E! ~
. v m1 e8 e( G) d; `3 |};" o1 t, c+ L* ]2 P, c: _% C1 o
3 A: ?, V6 L2 N' n9 ~
; `: n$ m/ k/ W$ d' c; g
// Dummy Implementation to be used when no other implementation is available
0 k5 T: G9 f/ e, u) g) E$ m! h5 Y! eclass CUPnPImplNone: public CUPnPImpl {3 ^" E4 Q- |* R g
{: ?2 N- G, A7 \& m, f: ]
public:
2 x2 [% u* z" \5 n7 I virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
' o4 [. t. b2 q$ Q; }8 n. Z9 P virtual bool CheckAndRefresh() { return false; }0 h, L" b7 |' e! ?# ?' [
virtual void StopAsyncFind() { }: r) i) M w: V4 g' d7 u4 ^
virtual void DeletePorts() { }
3 n) s& _8 ]/ M. p. ]$ P9 s. { virtual bool IsReady() { return false; }' ]& J" ~1 |. y
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
8 S R2 S% w j" p};& X/ G! X2 Q9 f' m
- _9 C; a0 r6 m
, h+ U0 s: s$ ^$ ]/////////////////////////////////////! K+ K9 m+ Y' ~3 M. u$ F9 @2 x' a
//下面是使用windows操作系统自带的UPNP功能的子类* @' I6 | G% w1 `
( w- ]2 p+ S9 g/ `* u" I# |. m+ x D2 a# x: f7 e `7 N: O
#pragma once9 ]' q9 J/ f/ V
#pragma warning( disable: 4355 )
. D, J/ K3 }- J, [5 `4 b# ^9 ~7 I
5 Z* |; i8 L1 N% P F4 D M r- r5 ~" G4 R( K
#include "UPnPImpl.h"
7 B( F! {1 w d9 ~/ a( J9 c5 Q#include <upnp.h>$ Y& j) d0 \( G L' `/ p& p
#include <iphlpapi.h>4 E1 u/ T% a& S4 `& J" J
#include <comdef.h>
, c2 r% ~9 p+ d% |# J# L#include <winsvc.h>) j. ?: O. N, g# a
$ f& S& C0 L" J: q& C# F* D
+ \: n9 G, F; n( W1 @+ I/ A0 t#include <vector>1 t3 W A$ \! O: X R% r
#include <exception>2 r: u) X3 c5 F9 N0 {4 L1 r# \1 R
#include <functional>
' P% `' F( G9 a* P& K; g( w5 c6 T! G( v- _2 l E
, x3 C; W$ m# E
% [, V1 C' _: E# r8 Q6 l0 q/ O( A3 y# g1 M' ]! c6 c
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
* m+ l+ y% |, X6 `) xtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer; |. [5 L/ a9 {7 E4 G9 d2 q, Q1 o
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;, K. Z9 q! c. J1 X+ G- U3 G
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
: A {! m/ [4 ^5 @" P M3 xtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
- s# t, ]8 R+ p) Z" D6 ltypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;! j7 S" M: ^0 u& y
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;7 w" Q0 g. o( p- s" l
0 f g# ~+ x' }/ E
! c0 M, @0 b% C* K! Mtypedef DWORD (WINAPI* TGetBestInterface) (
" x& b5 d, \' y" K, M7 q# {5 c IPAddr dwDestAddr,
* {: ]. f& S# b; [ PDWORD pdwBestIfIndex0 Q6 d: _/ S: U/ z/ b2 N1 }! d+ w
);1 C, L& o% m1 E& k! ^
. _; Z( _# k2 T1 Q9 j& _8 A& i/ C1 ^1 v2 [4 f' a% A4 w+ v+ D
typedef DWORD (WINAPI* TGetIpAddrTable) (
% \2 J+ R& R% T0 y PMIB_IPADDRTABLE pIpAddrTable,! k0 u5 ~ f! T2 }" Y( o
PULONG pdwSize,# h5 A) I+ K2 `5 H
BOOL bOrder
, d" H' Q, I2 u3 M- f);- v4 C% m/ k4 }0 n5 a, P2 H7 g
& k! P- J% w6 k/ @# h
4 M4 }- J* R, i, }. p9 T0 u
typedef DWORD (WINAPI* TGetIfEntry) (
; M. f: V6 U0 W/ s+ K/ [6 t3 _ PMIB_IFROW pIfRow
2 R# l/ z! j. \ t, b/ z$ l8 {" B);8 v# d/ D9 b1 {3 t0 \' W$ m/ f
7 ?% h. b' h6 d' m4 m) \/ q' t0 A8 Q8 b
CString translateUPnPResult(HRESULT hr);5 K- d& ]) n6 z
HRESULT UPnPMessage(HRESULT hr);- w& ]; p% z: P2 U+ q' D( h. A
% ]/ W% N2 V, K% m+ k
# E" P$ Q9 [, Q
class CUPnPImplWinServ: public CUPnPImpl
9 L0 [, j: e1 h p+ j' X: x3 |4 ]; X{/ X/ c5 y y* M3 y/ t3 V" p: W
friend class CDeviceFinderCallback;% x0 {$ c: ^ H: k
friend class CServiceCallback;
- A6 ^ Q! _3 ~- {// Construction3 p- m- w. B! U# p
public:
+ g, i i- N; ^4 D* |! r virtual ~CUPnPImplWinServ();% f+ \! V- x) n* }9 o, ?: S
CUPnPImplWinServ();4 |8 @2 m$ Y& s- S% R
2 ?% l+ t$ a; m) X- c8 G9 o
% `1 G$ t! v1 U! l! E- o4 d' |% w; D- P virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }6 p) r8 v" {: A. c# E1 ~+ X
virtual void StopAsyncFind();
" ]) y* S# }) _: u virtual void DeletePorts();
! S4 E4 x/ h+ [" g virtual bool IsReady();
3 ~4 ]! X6 @3 J- d virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
q$ U _# v* t! d! P7 ^, A8 C& ]/ r" j
: k+ P( A/ V( J) w( }& m // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)6 J: H B2 U# Z1 a* T1 w! p" |6 B7 y
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
2 z; E$ J( S3 R3 D& } virtual bool CheckAndRefresh() { return false; };
! @2 c: B' \' F3 [; J% p% _# j. M/ ~4 r. r# R+ A* q
5 a" ~: J+ M Z& ^( W$ ]0 i" U
protected:0 J' a$ B! ~$ M" k
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);& }5 z4 V! O" J. f7 ~
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);6 x; |2 X5 g; M g# u8 h3 Z$ |
void RemoveDevice(CComBSTR bsUDN);
+ M9 j$ m+ O2 c3 r* R& C3 y. g$ N bool OnSearchComplete();
D( }5 [3 |2 \& T9 b; y. W void Init();; [ a2 a2 G5 ]4 ?
# T2 ^; H2 l5 |/ V& p$ f# o1 V4 z
" o1 B( M; u9 y* D* T1 ]/ b# `0 C inline bool IsAsyncFindRunning()
7 \9 q6 w9 Y8 B T {
1 z1 X3 T5 v Q I( C8 b& j if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
% g5 ]& a4 J5 R8 s# V3 }# X8 u5 R {4 I8 @1 ~, o9 h# P8 x
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );7 `! ~/ m5 g. y) C Z$ i
m_bAsyncFindRunning = false;
- |% K/ t, v* `5 t L; z }3 m; Y% C! x3 r3 S' S
MSG msg;1 ^) L/ v6 i1 ^( d. o* ^& A
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ); ?# Y @: h1 x t
{: T' [& P9 N. c* Q- c. X4 u% C7 _- k
TranslateMessage( &msg );
" S6 G: S4 R% \: [5 ?, H( B6 u/ d DispatchMessage( &msg );
# q5 p6 E" Z# b. n) G- v0 L1 a; d+ F }
9 ~ g$ E `7 E" | return m_bAsyncFindRunning;1 z/ j) ~2 U) V: T
}
4 O9 p2 u+ g* n# Q! K: [8 E. c0 z6 c K7 j# W8 Y
' `/ \4 d$ N2 ~- { TRISTATE m_bUPnPDeviceConnected;: h, Q5 w* D6 I2 m+ E
# k: y5 T* B+ p9 b& z U7 Z+ o& t& r! q9 R7 s2 s2 b
// Implementation/ B& C" v3 V2 D5 Y0 J2 t$ e5 y8 b
// API functions9 h1 F x O# { f1 }
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
; \2 ~9 ?0 q, ?2 Y: L6 _( Y4 T% C, y SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);6 P: |% y# p- ]: G% c+ b
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
6 a( d" r: L q! v) N, C BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
+ N3 ?( C$ [ {$ l3 p& u BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
, s' K& e/ m! b# V3 Q( v BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
" Q) L3 K: S$ r1 C3 O1 v" U, @$ V& c
( `# f7 i1 k N& X: | TGetBestInterface m_pfGetBestInterface;/ B# F- \( {9 l
TGetIpAddrTable m_pfGetIpAddrTable;
d4 ~, Y! F9 {4 |3 k5 n TGetIfEntry m_pfGetIfEntry;3 o* ~2 i& ^" m: G
2 c5 ?& E- b! E3 A2 b$ v
/ Z Q& P) X2 b+ @5 w
static FinderPointer CreateFinderInstance();+ x; `% Y( \) [- U
struct FindDevice : std::unary_function< DevicePointer, bool >+ ?4 D# E6 _8 M- s% Y: x# M# k; k
{
4 U" |/ S: S9 k4 k% n9 X7 }: P. p FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
+ p" [4 y) t- l1 E& y result_type operator()(argument_type device) const. S' p1 f7 R" A' m/ t% A% Y4 v
{# `6 _2 {1 o# H9 c% T
CComBSTR deviceName;
+ u6 f3 R. M( U9 F HRESULT hr = device->get_UniqueDeviceName( &deviceName );% ~8 L- u7 }- J
6 |' o5 A& d. I% L4 E
- j9 X$ `& O+ P$ @6 F8 g9 n ]6 f if ( FAILED( hr ) )
6 ~3 P7 V& N U6 m" T$ Z( N return UPnPMessage( hr ), false;
5 ^4 T, W% W9 [9 U* E+ a: |7 q" ~
9 H4 Y& {& O) z. S+ k' ]; R C5 ]# a2 K6 {- X. \
return wcscmp( deviceName.m_str, m_udn ) == 0;
+ v9 T: f: ^! i" T; d/ e }
' m: n# t( |3 O# P0 y" U+ O CComBSTR m_udn;
' z( L. L: ]" r };
4 C% L5 y( Z% ^, d& ` N
& S' u% H' `2 ]5 [ void ProcessAsyncFind(CComBSTR bsSearchType);
+ y& D& k. U$ R/ A4 Z; h: Z& K. ~ HRESULT GetDeviceServices(DevicePointer pDevice);
# x1 y7 a4 F/ a2 R& c' U void StartPortMapping();( u$ h" K4 z* u' C1 C5 s6 p8 b
HRESULT MapPort(const ServicePointer& service);
) L$ c3 |+ H& h o$ A: Y void DeleteExistingPortMappings(ServicePointer pService);
, {! \4 s L$ s! h& c c1 i void CreatePortMappings(ServicePointer pService);, m! H( ]8 g9 F4 r
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);& S& l) W% d6 H* x6 ?
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, ; \$ B: n; X( L" U) O! N
LPCTSTR pszInArgString, CString& strResult);# j: ]2 }6 i$ C* m) @
void StopUPnPService();8 f& Z. |. F( I% h& ?* h
1 t7 `5 |1 z" N/ r
; B: G1 } {; g1 a6 b) G+ L6 o
// Utility functions
0 e5 O( e1 ]- r8 E HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);$ _% t5 d! z/ ^8 u& ~% ?
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
; H5 V( j6 X9 M. }' M5 c S INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
$ W$ W. G7 T0 n1 X9 ]0 r, h void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);9 V+ b$ F L" X8 ]3 _" ?# w6 { a( L
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
1 J, a$ k. K3 I7 J8 `; h1 i! D$ H4 ^ HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
+ c' o5 y2 n J9 a CString GetLocalRoutableIP(ServicePointer pService);
) E* `- k7 u/ q. e) s J( _! w, u, p* \" Z1 K
2 {4 J/ `! X7 l& v- B// Private members: ^ m T* V+ [- V5 y/ G
private:
t" n+ s+ c' i# d DWORD m_tLastEvent; // When the last event was received?% D' m/ H3 K2 b% J
std::vector< DevicePointer > m_pDevices;
C# F( r$ |9 X6 d/ w+ W+ w std::vector< ServicePointer > m_pServices;6 [) f% }3 a( R9 H3 E: s
FinderPointer m_pDeviceFinder;& C7 P1 \: |9 }* A L& n
DeviceFinderCallback m_pDeviceFinderCallback;
+ [. b- |5 A O) ?! }! V& W' L ServiceCallback m_pServiceCallback;
* w0 V/ ^( A* S! T0 u2 l4 K2 l; B2 j' N8 l9 R5 x
3 H: _: b/ n: P: } LONG m_nAsyncFindHandle;
9 u k# n& }1 ?3 Q3 D5 \& I$ a bool m_bCOM;' n7 |* ?$ {5 C' ~1 ~% e
bool m_bPortIsFree;5 ?/ P D# K; ?6 n- B7 Z$ r; \
CString m_sLocalIP;* X4 `$ M# V( `5 _
CString m_sExternalIP;9 _! X& n$ l, t# W
bool m_bADSL; // Is the device ADSL?0 |6 i, P2 p A K
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
6 C1 a( J1 H0 _ bool m_bInited;; ^7 M) D2 q9 W
bool m_bAsyncFindRunning;" M$ m# r7 b3 m! [
HMODULE m_hADVAPI32_DLL;7 g3 F2 c! X# t, D) k
HMODULE m_hIPHLPAPI_DLL;
1 \ E* D0 e2 v3 K5 ?7 U2 i bool m_bSecondTry;9 C/ y/ w! P- }. i- y, s. |
bool m_bServiceStartedByEmule;2 D+ h" a0 K+ I7 {
bool m_bDisableWANIPSetup;$ m4 d% S+ U: W
bool m_bDisableWANPPPSetup;0 b9 S) Q- X8 s
8 } X$ S% f2 B- D o1 D5 ?" t% h j& ~% Q9 e
};
4 T7 T3 H0 `+ v# y) i( a( C0 R2 Y1 {. Y/ l7 J$ L; e
8 p. g2 k) u/ l- L3 s% [4 e// DeviceFinder Callback0 ]8 J: X" u( i' N! ~
class CDeviceFinderCallback
8 Z: q% e4 A( K! u: ? f : public IUPnPDeviceFinderCallback$ R* \! z$ }5 G4 y4 F. ~
{- |# I8 s% C& ~: E1 ~
public:' ?. `3 A* i) W
CDeviceFinderCallback(CUPnPImplWinServ& instance)9 K( I; I+ G' c I0 f( V/ O1 ]
: m_instance( instance )
6 M, w/ r4 E0 `% z1 n7 K { m_lRefCount = 0; }
8 s" A( h1 m6 f; e: k# E7 Y
- h ?0 v8 D. Q6 B+ x# o3 k; n3 d/ e, b
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
) e$ X6 c5 e: G2 B- l8 E8 @ STDMETHODIMP_(ULONG) AddRef();2 ~0 o, C, o9 [8 g' j$ \
STDMETHODIMP_(ULONG) Release();/ ?" Q- d; Z: [ m F1 ^' Q3 P! n' {
- d, y$ C% |" L: ~7 d3 G4 j$ J/ a7 g+ ~, X5 {
// implementation
' W2 t0 w! U+ ?' E2 G s0 Rprivate:
( X9 }$ l g g# w( o. x9 _ HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);7 g' f( U1 F3 \: p5 j) s( Y' d
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
, O; S" y0 u. M HRESULT __stdcall SearchComplete(LONG nFindData);
( i" O4 V. R! u8 V- j/ C! o3 z7 d. N6 k! r
7 n& M9 L: x# c/ E
private:- c) b& X: {5 u( U8 M; [
CUPnPImplWinServ& m_instance;* Q; d* H1 y* v5 F/ E3 c# T) B* O
LONG m_lRefCount;4 r. L6 b# Z1 Y L
};
0 F+ i( S0 d* [' D/ }
: z$ l+ u% J8 F7 c+ X3 D/ r% V) V+ d1 J; n4 O/ e5 e6 Z" h `
// Service Callback
1 @9 Q9 p: @; c: M8 ^5 h' O$ U0 dclass CServiceCallback
- h9 ^* D, t4 W' M5 X, B2 I9 e : public IUPnPServiceCallback" J D% O( {9 ?4 @
{
( N; n3 y& z) t G$ u: N* Apublic:0 d ^+ e+ t; [) {, X
CServiceCallback(CUPnPImplWinServ& instance): V% j- P0 }6 Q2 ?8 O, T
: m_instance( instance )
! F& C+ C% M$ x4 c' S: {( r' A { m_lRefCount = 0; }
8 k* W& v$ Z' L$ P% z6 S 9 t0 @& ?! C0 z
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);1 O& @: n2 k# {0 [( I, v
STDMETHODIMP_(ULONG) AddRef();
, z, Z8 h% p4 Q0 R" O; `$ B! s STDMETHODIMP_(ULONG) Release();8 q' ?5 H9 r$ c/ Z9 p3 {) t
) L1 g- d, d/ h5 G& u- T2 n4 E9 f+ F- D
// implementation1 k9 w7 f1 K: W9 G
private:
. E+ B# e# g4 N; k HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
; I$ d7 {" ]$ _ HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);) w* b' [& s$ f/ L( Y
0 ~2 O: B8 X; K3 l9 V* Z6 F M- w1 R6 W' c
private:8 b' I, B2 e0 t. L+ @4 m
CUPnPImplWinServ& m_instance;- c9 u+ H, ^' [" W' L
LONG m_lRefCount;5 }: G9 Q' |7 m
};
% d! H' U" K3 {8 F6 f, O, f8 D; T- c1 S* f* w' m. \. n
! F, K; x7 a- I* I' b% S3 G% Q7 N6 Y
/////////////////////////////////////////////////, _* n; W7 t! s8 `8 [
0 Y5 s4 _) s; e* O. H8 J
$ r$ i: L9 y" S1 [7 P; r4 X
使用时只需要使用抽象类的接口。) A; }* O/ }! W! {( x) H3 U
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID." m* y( i+ J2 g2 [8 m
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口." k+ `' g, ~! k3 ^
CUPnPImpl::StopAsyncFind停止设备查找.2 R1 r, a1 [# l! D
CUPnPImpl::DeletePorts删除端口映射. |
|