|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,8 J% G, ]8 m$ m+ f1 y
1 b3 T4 ]5 s: ?! j# r2 O! u" H
% `$ {0 k7 j) Z9 L# \///////////////////////////////////////////
, q- s5 B+ X! ]2 G' R3 W7 e5 U8 R( l//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能." @+ k+ p; M8 {6 G6 n3 ?5 a1 B
5 g* n+ M* D+ e- k8 K7 T9 e
4 i2 C$ U* _( R" |3 x0 |# f9 \( z
#pragma once: ?9 M+ b* D h% |' j1 `
#include <exception>- c) {/ W: S4 l4 z4 J9 \; V
& \% U/ C$ B) m3 p
2 w5 ]& C$ e/ U( @* P enum TRISTATE{
; m1 M! [6 K6 q9 [) z1 \% O z J TRIS_FALSE,
2 Q& G9 ~" i, A2 T! y* ?0 U TRIS_UNKNOWN,
- `% z" f% j& r; c TRIS_TRUE
* X& c4 O2 F, \' S3 r2 L0 ~};
# M$ r5 |4 ` n9 x* A) K
, E7 u6 V3 o2 S4 x' [4 ^. i d) Y
enum UPNP_IMPLEMENTATION{
6 g; [4 U. }! L UPNP_IMPL_WINDOWSERVICE = 0,0 x5 `% |! ?& ?' C8 N" W! j, o
UPNP_IMPL_MINIUPNPLIB,
$ j5 _4 @, l4 r UPNP_IMPL_NONE /*last*/& X. F7 G- Y$ s1 G5 W& Q
};) H3 l) p. M% a& {# {) R. G' l
, ~$ \; Y- v6 t& m, F8 H
, g, E! E3 {: G) A
6 C; m1 ` v$ h5 T1 l) k* j9 K1 l8 o% Q7 X* i6 R, A. V
class CUPnPImpl
4 a; Z" W, x" v: q{
4 T( A% [3 H: G: o& O. n+ O6 gpublic:
( H$ @ [6 c3 v! B7 T$ _/ n CUPnPImpl(); [8 u8 G3 c4 o: R, w {8 Q
virtual ~CUPnPImpl();: a* `- I7 y' L" ?5 u! O
struct UPnPError : std::exception {};5 e* G4 K$ R5 H- I5 t, C) b. f
enum {# _! v0 r* Z/ M7 a# U
UPNP_OK,* p- q H' [2 A: z/ I* E: P/ X2 Q
UPNP_FAILED,' Q. v* X; T7 S4 O r8 ^) q
UPNP_TIMEOUT
" i% X6 {' z/ G' Z };
$ ^) |! s% ?9 E+ @% |4 m1 H
8 x( r e% p8 ^; D4 ]: W# }9 h/ }6 p2 l5 w2 q
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0; t) a) g# f3 [
virtual bool CheckAndRefresh() = 0;* Q! M) Q k7 N: B. e$ i, g, e
virtual void StopAsyncFind() = 0;
- U0 s _* V- T3 u0 f# I) A virtual void DeletePorts() = 0;
$ L/ ]1 }! r" L) ^7 ~% F5 V" c virtual bool IsReady() = 0;
; w* q* q+ C. o2 ], | virtual int GetImplementationID() = 0;1 [5 d! z# e2 W7 T
& O& a6 x) R2 _% s6 d- O void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping1 c5 T+ A6 m% y/ J/ L$ Z* W& x6 `1 r
4 J8 R# W" h. e9 }8 i& a2 @
; \1 M6 \8 g- q5 F/ A# p( T( C$ B7 F void SetMessageOnResult(HWND hWindow, UINT nMessageID);1 j) l0 W B s- j
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
1 g Q+ ]0 y+ C' W uint16 GetUsedTCPPort() { return m_nTCPPort; }7 J+ w8 R" i) O0 f" A" G
uint16 GetUsedUDPPort() { return m_nUDPPort; } 2 o5 \- L0 X- H- x& L; {2 h/ Y) d
h# {5 g7 A( U
" {! `2 d7 y) v+ Y4 p1 q$ m/ N" `// Implementation& X- S1 y3 j! Z0 c1 d$ G3 Z+ Q
protected:' Z& M+ A& e! a) \, \& r8 ]
volatile TRISTATE m_bUPnPPortsForwarded;, Q6 h2 ~3 O/ a( ~$ M0 ]* i
void SendResultMessage();# _( p- D6 w* W$ ~" H5 n
uint16 m_nUDPPort;+ A; C; S' @) ]5 {& C
uint16 m_nTCPPort;' K& I2 d) F. | I
uint16 m_nTCPWebPort;- p ^, {* {: Y8 a2 b
bool m_bCheckAndRefresh;
" g8 H- p; X% {/ F( J4 Y+ M7 V3 ~! C
" ?* O( O$ z( E9 c- q* [5 G! c" p
private:
- R* \% n1 H! l( Y HWND m_hResultMessageWindow;
: v1 W2 _8 z) S$ z UINT m_nResultMessageID;
8 U2 t" E" j. P9 W i% y; {, z
0 H: _/ ^4 {+ b) C. z& w) _8 c% d4 B5 \8 q1 |0 l& h, k- @
};
0 u+ I2 ^- l) @8 Z6 i* j2 u
c) e! g4 c3 X! m4 K/ s
. I* _" l3 ]0 v- ?0 I// Dummy Implementation to be used when no other implementation is available6 c" F2 m# Z* L3 y+ J
class CUPnPImplNone: public CUPnPImpl5 ?* m4 A9 Z4 b% E% D/ o
{4 i( o5 Z- x' B8 ^* J. J3 A8 ?
public:
2 d! K% D1 R1 W. E! X virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
) y; W' D2 ], d7 d: H4 U. L7 D6 _9 m virtual bool CheckAndRefresh() { return false; }
1 v& n8 z3 T; p" Z( h$ c! w virtual void StopAsyncFind() { }
7 G8 U7 l# E- z; ^7 \% N virtual void DeletePorts() { }/ A: M) T0 l' r* S& ?, b& l
virtual bool IsReady() { return false; }
1 m( v7 j7 r2 h* h0 l t virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
8 g( ]; |( P) }9 C' K};# Q2 o4 d) W( V4 }, g
) z& q1 M* V3 G: Z7 B4 X/ H
: _4 U$ i( [6 c8 d& ?4 C2 s- {/////////////////////////////////////
0 S9 {0 K0 v7 O h2 ?1 ]4 [//下面是使用windows操作系统自带的UPNP功能的子类
8 R1 d- Q5 M) r) T/ D* a& M
& x2 @8 S/ s9 M4 G; k+ [6 U5 u- Y% l
#pragma once
$ n7 o- M& Z0 g0 @, l. `#pragma warning( disable: 4355 )
' k" C5 ]5 f g. Z
# t( M* Z; d0 G- f2 `
" M, }3 D8 M0 y; J* E#include "UPnPImpl.h"
( x1 T6 s. s; B$ G+ c#include <upnp.h>
$ @* {2 s" D1 l6 d9 _4 r H#include <iphlpapi.h>- |; e' R9 s! y" O
#include <comdef.h>- p& g) K2 D1 h% U
#include <winsvc.h>3 k" u4 q) b5 z9 P: y7 C- j
9 [5 y& k6 M* @9 }0 r
' Y$ K: W4 l$ U0 ?3 p#include <vector>
/ w5 h2 L% B" b' F1 C#include <exception>& U/ b/ H- g( q5 a8 S6 q6 v
#include <functional>0 \! E* `, I/ T4 ^; J4 r; v
2 O" b& p- j" b2 d, e. i: |1 X" \# e8 s( F, L6 y7 I* o$ ^
0 o$ p$ b2 {2 Z- {7 e" @, Y' W3 r( X, ]$ X$ g
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
/ k: F2 z& `- \0 R* Mtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;3 S1 \- T @, w# U" u9 T* X" m
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
2 {& l, p+ J& I, Wtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;" y; V. [; n, Q# \
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
, x# t) ?3 s, L `) N* {typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
. z& H8 d! J; ~; s: l6 dtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
& R; B" b, G' f0 [! q& j0 M0 K8 C3 A9 C& J: W
, B3 J$ v( y' `6 H/ i% G1 S
typedef DWORD (WINAPI* TGetBestInterface) (9 P& P. E! h1 [/ C% y
IPAddr dwDestAddr,4 m0 J+ w. A9 N7 A4 f
PDWORD pdwBestIfIndex- Q/ L/ d2 i' U$ R1 B- p }$ s
);$ H$ \8 q2 x! Y: |
2 j; v% h; K. @. C* p1 F. Y3 p2 M0 @6 @
typedef DWORD (WINAPI* TGetIpAddrTable) (7 N [; B8 f8 v
PMIB_IPADDRTABLE pIpAddrTable,
3 N @7 _( M, G* C1 g2 u PULONG pdwSize,
5 x" l. V! w4 i8 u) A6 N BOOL bOrder
8 e' ~, X' p: w8 S w);
, i- }. ^5 y0 i' g0 x( w0 B1 N+ a3 s7 n* b% g' G+ d# x
* `5 Q7 A1 R: {" O3 p2 m
typedef DWORD (WINAPI* TGetIfEntry) (, r+ u' N3 m: P" a
PMIB_IFROW pIfRow: l2 O# Z: l5 I
);: m) ^: f9 W4 D* L
( ~6 n$ |! {4 a0 \) l+ m. @$ A, d+ n" h( H( R7 u4 h: ? `8 l: d: H+ D7 N
CString translateUPnPResult(HRESULT hr);
1 c! o) w/ j& A0 THRESULT UPnPMessage(HRESULT hr);$ E) c/ h$ o2 m
" E0 Y: G* U9 h: X
/ s5 H e$ s2 c* X' Sclass CUPnPImplWinServ: public CUPnPImpl1 j" }' U" ]6 i) y. }
{% u( _: i, B- o) h- Y" V7 z
friend class CDeviceFinderCallback;1 C6 ^1 u+ w3 l' y5 ~2 V- t, o
friend class CServiceCallback;
" l7 Z, S2 B; E8 [; L! o4 Y! y// Construction
4 D, y4 O' X1 Z6 J2 l" f2 l! Upublic:
! \1 E# {' ?+ {; C3 A virtual ~CUPnPImplWinServ();: O; g% ]/ {( P" T; s. s
CUPnPImplWinServ();
8 Z1 B$ S9 }/ A' V5 C! W1 a% M/ B. W
' z0 Y) E& q: R8 f Q3 I; s
6 _! B k2 F$ i1 L5 |7 S O7 F virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }0 @+ S% i, a7 a$ p2 C
virtual void StopAsyncFind();/ l4 V6 W4 W$ H- Q
virtual void DeletePorts();
. Q( @& W1 k- H) ]% s; _ virtual bool IsReady();: g% z8 L! c9 j# ^) x; w
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
4 V) S0 [, f+ g. S5 z& l/ Z' S. ]) d( }) i
5 I6 _# m8 M7 z5 U/ m; W ?& Y
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)$ [' v7 I: N4 T# \( e
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later+ q, i" X% V2 @, r
virtual bool CheckAndRefresh() { return false; };
, i! z" F( G4 I- z+ R% \) }$ V* K1 t: }2 F8 X9 S: O
( H1 N& B. @% o [$ Fprotected:# [6 w* _$ l, j0 k4 a9 N2 ]0 p4 s
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);5 E2 e7 h+ Y% x8 Q$ V. Z3 g
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);% ~2 [6 c. ?/ u+ A
void RemoveDevice(CComBSTR bsUDN);( c }. S2 _: o( O
bool OnSearchComplete();
( v" n- @& R1 a5 _' I2 [ void Init();
. `' y- W; M) @
7 a' u+ g) Z+ O6 u$ f8 t+ o4 z. @7 C4 S3 r/ Y
inline bool IsAsyncFindRunning()
6 b" {& X) a! E; \) H' ]# p: q {
, f0 m' z$ ^" V% A5 @2 d. R* N( u if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
$ `$ S* L6 R8 k5 w4 M {. E# w" K! e8 [% o
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );- F8 ~" U% I9 O9 u# o+ x% I
m_bAsyncFindRunning = false;
$ A9 n9 ]# H0 I8 |$ a6 a }1 g9 B# g$ }0 U$ c) C" t
MSG msg;4 e4 m, t. [# ], N3 C& m" m* }
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ), C1 ^8 m5 v I, u2 H! W% N0 z
{
( c8 d' o; Y$ u. J- l' t TranslateMessage( &msg );
+ f) ^8 a" P% g/ X( ]4 H DispatchMessage( &msg );
1 Q" L2 O5 f! a, s7 j }
# I$ D. G2 {' F) z8 L return m_bAsyncFindRunning;
0 I0 y+ A4 }. b' ?! R }8 \& e- P/ h }: Y% S }
* r+ @% E5 {* ~: E# h7 |3 y) Y# v( f5 J$ \2 G4 m' |0 Q- ~) n% X
TRISTATE m_bUPnPDeviceConnected;
- ]/ J7 r% [4 [& {( J8 B
2 W0 k* C7 ^ Z w: G0 c- }& ^6 s& M0 x- }- U2 G3 y) z- ]
// Implementation
7 i% ?/ E% {% k' I F( ~/ T // API functions3 l$ |$ W( n* P. M5 S
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);+ S7 n0 M4 B* s0 d" N. `( F- l
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
$ ]6 x- y/ @8 E, O BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
+ I" X* @) v% w. |2 j' P: k BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
) Q" h: N+ v/ F* N BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
; j, E" M! }( b$ T- s BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);; |/ K$ B* s4 D$ l1 z4 M
1 H; h+ o0 }& Z" K7 p) `5 f7 x* m# R2 V: }( y& X
TGetBestInterface m_pfGetBestInterface;! g4 G; ]3 A/ }/ z, p' k! x
TGetIpAddrTable m_pfGetIpAddrTable;
5 t$ h) [. H7 T0 d TGetIfEntry m_pfGetIfEntry;+ _! k, o! h) l' L6 D) Y) H
1 x$ o2 V' m1 ?
; R' j" ]: P, d# R
static FinderPointer CreateFinderInstance();0 @. H& F3 `7 Q9 }' V8 E
struct FindDevice : std::unary_function< DevicePointer, bool >
& {6 l' [! r* k6 \+ H7 C {3 ]3 x# M6 m0 S6 N7 o* F
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
: O, n. z4 _( h2 T$ f9 B5 @( B result_type operator()(argument_type device) const
' i1 y3 T: P5 v3 W {
7 Y: D$ D4 P8 D; g h# w CComBSTR deviceName;
/ p, G. j3 @9 k( A, {: H HRESULT hr = device->get_UniqueDeviceName( &deviceName );
]1 M2 h5 C) B
6 s9 i, R3 l! ^2 W7 j# l: T0 \8 K3 H/ }% d$ e# v1 C0 @: D/ Q! `
if ( FAILED( hr ) )0 j- J0 ~0 }0 q$ X) C1 d
return UPnPMessage( hr ), false;
" s5 \8 }# ^ u4 y' E9 D+ \+ G) v9 N
6 {7 s4 m6 {% e return wcscmp( deviceName.m_str, m_udn ) == 0;
6 F* ?; X: q, f2 _ r3 ^ }
" T, J, E. x4 Q& B, n/ N8 G CComBSTR m_udn;* N* c% m: z% v, E$ X
};
* D# y7 g) w6 H: o 8 Q8 F" d* |( h
void ProcessAsyncFind(CComBSTR bsSearchType);; Y. C8 P" o% I' n
HRESULT GetDeviceServices(DevicePointer pDevice);. q% [. I$ h. t& W2 d. s! r
void StartPortMapping();! o# A/ H. U; s
HRESULT MapPort(const ServicePointer& service);( y9 J" O' d+ G! B Q: ~- A* g, S
void DeleteExistingPortMappings(ServicePointer pService);
/ b9 d' q s7 ~$ e; [. o void CreatePortMappings(ServicePointer pService);6 e5 m9 O2 |) |. X5 q' K' m
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
. n2 h7 k4 G3 A4 e' [" P# X, W" e HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
5 y3 f; t& w% k% D& ?3 A LPCTSTR pszInArgString, CString& strResult);
+ `% ^+ m+ [% r4 t( }/ o& L( ~# g# f void StopUPnPService();4 a/ V# r9 g, @& B
9 H* t! Q: Y! F, C- O
( @. _! ?! ~2 W* D" J // Utility functions
# {2 a* ]% G7 z7 b& A% ?: w HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
' n8 t1 n u* d' R" A INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
. R. ^- `: ^3 s INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);6 r c' [3 u1 y" ]4 N1 y, v
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);' a" I5 n" C+ \" c, g4 K8 L
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
; T* v/ h/ }" S( ~' d HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);# `# y2 [) h* t- C& l& c5 w
CString GetLocalRoutableIP(ServicePointer pService);& a& x c% {2 b! W
7 Y4 q4 M% z3 ~
2 p& \# M& ?% F// Private members
: M& W8 K2 x9 @ u! U% j, a' Z0 r Lprivate:& E7 j) _$ { F, U" G% S
DWORD m_tLastEvent; // When the last event was received?7 ?7 T; L. [# ^% b0 L% v @, }
std::vector< DevicePointer > m_pDevices;' y* w( H, U4 {) l0 y
std::vector< ServicePointer > m_pServices;% p- E+ R# P9 @. Q7 W* F) y; I( u# x
FinderPointer m_pDeviceFinder;
" I1 {5 g5 m( a3 x$ K) m DeviceFinderCallback m_pDeviceFinderCallback;2 l: T2 l* y" a
ServiceCallback m_pServiceCallback;
4 K4 D6 ~! x, L: x* K# w; e/ s4 f. i0 Z2 {% G- a
) s+ ^2 _; B8 n+ @/ I$ d" p6 O! M; _ LONG m_nAsyncFindHandle;
& p, c1 W8 r0 v) u bool m_bCOM;
; e/ a* y6 x) C bool m_bPortIsFree;0 Y# o1 V- ~# I/ K! u: V0 L
CString m_sLocalIP;' e1 f) r" b, S2 i( B" H! [
CString m_sExternalIP;; a) ]5 |2 i; Y4 Z2 A
bool m_bADSL; // Is the device ADSL?5 @& ]. U* p1 K, w8 p- N
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?- D/ q) V/ H: |+ m8 J' ^
bool m_bInited;
( e7 e6 e$ p2 [& x4 @# x bool m_bAsyncFindRunning;
2 v+ F6 s$ C) m' T+ [ HMODULE m_hADVAPI32_DLL;
2 |. e4 L* j8 X- x" Y HMODULE m_hIPHLPAPI_DLL;8 d9 P1 E- Y' \1 [/ }) O* Z) t
bool m_bSecondTry;
6 ?. Q6 m, }% L4 ^% h( {# \- x bool m_bServiceStartedByEmule;
9 y9 x3 K5 H/ ^9 L4 m7 O bool m_bDisableWANIPSetup;# r* @. q$ C. A# _
bool m_bDisableWANPPPSetup;" R3 C( n1 `& I. Z; O% y, H
1 T3 O" {* E* o8 W# e
8 D( J k' \& t: a$ L7 F, n6 ~};
; Y* c8 ?. F. T( u( A
% T" D3 r. L5 J, v5 _
: t& E! N+ b1 x- c" g// DeviceFinder Callback
# H/ H: S- E7 Z- G# uclass CDeviceFinderCallback g7 n0 A, P! V, S5 c) q$ v: w8 T
: public IUPnPDeviceFinderCallback% E+ k% |: s: @% @2 g% v% l% r
{
5 }) G5 B M5 I* P) x+ c5 M: A& Q1 |* A/ npublic:% @& g x0 }* d- N9 o9 E/ k
CDeviceFinderCallback(CUPnPImplWinServ& instance)! v8 V: e/ F. ~ p( n
: m_instance( instance )8 T1 k* _, T5 ]9 }
{ m_lRefCount = 0; }% \; n* J6 Y& d/ e+ s
! z4 _4 ]! h. b/ K; ^8 [
' v. ]5 L+ L8 C) _. ]0 h
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
; A0 ]) c" {9 o4 f STDMETHODIMP_(ULONG) AddRef();
3 w9 H" H- V9 n) S9 [ Z STDMETHODIMP_(ULONG) Release();% a8 Q* Q# h" w7 B
& i1 g0 t, w1 O# H! H2 s
, Z6 }/ y4 u+ n4 x+ c9 f+ t
// implementation
; w" T5 C3 I) i/ K- v" G% d" nprivate:
, s. m- `+ _, S1 k0 c' ~9 ` HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
+ U6 _: T+ i7 x$ U, z+ T HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
% a7 T# X- k/ Z' w3 K/ S$ P HRESULT __stdcall SearchComplete(LONG nFindData);
/ X6 Q0 T1 k8 l3 ]
. d8 }* v2 J) _; }; Y& b1 {$ v* n
* X* R" s# H5 b; l- t9 V: [# Jprivate:& j! \- r3 j& A& U- J
CUPnPImplWinServ& m_instance;; v1 a' ^1 M* k$ _( y
LONG m_lRefCount;
) W" d$ g$ p% w( D};
$ B, Q4 V5 S/ q6 S, B
$ x7 m X0 T3 S9 ]7 \% V
! y* A6 v0 ^) D) o$ L// Service Callback
0 n$ e' E6 b# r' J ?& O. vclass CServiceCallback
( n0 A7 {9 B+ y9 R" B5 D : public IUPnPServiceCallback; I& D3 b2 _6 ?; C5 Q, I6 ^
{
$ J( [/ H! [9 k0 opublic:
+ a$ i0 j! m2 ^) Z" w CServiceCallback(CUPnPImplWinServ& instance)
: X- V3 }0 K( a3 }8 ^4 m! M4 X# j : m_instance( instance )5 O& I+ h, ^# j* @8 O% H1 R; ^* P: e% [
{ m_lRefCount = 0; }
6 C9 v+ z) X g, E9 H! j2 c7 A' Z - v% R( Y# D! g% i+ |
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);# X' J9 o7 I! G5 ]; s
STDMETHODIMP_(ULONG) AddRef();* r K- w" u" M7 M1 s* D
STDMETHODIMP_(ULONG) Release();
5 N3 E7 J/ j K/ r5 S0 u
! n+ s0 A3 N% b$ {, u3 t; X5 G& c" L/ C9 @
// implementation
( c% ?7 d6 T- N% Q/ y* ^ Cprivate:4 N6 z( h, ]7 o" f: U
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
s% C0 c( c6 u3 [ T HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);; B5 A8 D: f O% T( [: x7 F
/ ~! Q9 R3 {6 x, ?5 p# W, \
( B9 A- q b& Cprivate:% w9 ~: x$ M( F" O9 C( K: K
CUPnPImplWinServ& m_instance;
1 f' U/ [( |5 ` LONG m_lRefCount;
& s, C6 t+ d) C, m4 P};" a- d" g6 |2 A! I: p# p3 ]& x
' c2 J7 t9 S2 v' J$ O
4 e$ b/ t" I3 q9 r/////////////////////////////////////////////////
& N5 g1 s. Q' k' [' R& U0 m7 Z, Z7 _% S+ Z- r% e
' n' g( O1 j3 y% I
使用时只需要使用抽象类的接口。( i% V+ k: ?0 I' {& L
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
6 P% b, v( ~ B- b3 nCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
8 y1 R6 x+ |' P* N/ C# ?8 V, DCUPnPImpl::StopAsyncFind停止设备查找.
/ M: S @7 F$ x2 Y# r1 p8 i3 P0 BCUPnPImpl::DeletePorts删除端口映射. |
|