|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,+ m4 w$ A8 _" r6 z* D
, i+ ~+ p6 C5 r" r; U7 O) ]
6 z' p# f* W- c9 T, }9 H9 j///////////////////////////////////////////+ k6 g# X( e! B' y% U
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
e( n$ L) \; d/ U& J, _8 c% q+ m) b; y% q- [
! F5 G5 {9 s" }* X3 k#pragma once" Z! Y' ]) h& j) F
#include <exception>
p2 z/ P; [. L1 F& m- ^0 w! \; ]1 L; o; V, q! }0 [5 r
3 L) N' [2 R% x4 B
enum TRISTATE{
4 a! r$ Z( `* t- M TRIS_FALSE,. Q5 r! e, o% e0 _: ?
TRIS_UNKNOWN,2 D- o! z9 j% v0 M( {" V
TRIS_TRUE
6 C- t1 \) L: p4 |};
2 b: E: W6 N9 W8 _2 o
9 X' p7 s- v2 z- y X y- S
& ^* v2 f# W/ d" U! r2 n; Menum UPNP_IMPLEMENTATION{
' f9 C& V) `* O/ ~& k- ?9 p UPNP_IMPL_WINDOWSERVICE = 0,
) y) E- {/ r' R N# Y5 ?3 n) ]) _* ^5 w UPNP_IMPL_MINIUPNPLIB,' G" m* g$ K7 h) B6 O5 g
UPNP_IMPL_NONE /*last*/( h! T2 m. G# d K+ ~
};
0 g+ ^( ^/ X+ n* g
3 P2 {2 @1 I& v# H: q
: v/ V& ]: G, i( J
1 g V! A3 a, v) t- J# e( A6 Y# C+ N& ~
class CUPnPImpl/ f! }7 o& \ V' A
{
. ^6 X1 | ^. P6 z5 Q( q) n/ M, D2 U! Mpublic:
/ n" \3 w' j( C9 {/ K4 P CUPnPImpl();1 I& u# f# v+ `$ y* e8 L9 i
virtual ~CUPnPImpl();8 u O1 s; ~/ }( ~. H
struct UPnPError : std::exception {};$ r! v9 r3 j9 d) C$ {! U7 e
enum {
& z0 ^( a h0 o" i. o: T. A' i6 Z UPNP_OK,
( c6 O4 }2 G$ w6 X! ^8 G UPNP_FAILED,
* q5 o1 {- f; g0 s UPNP_TIMEOUT
$ s3 A8 }3 m1 O5 R, [( ?) z };2 q( }( o! c5 E
6 c4 h8 p4 ~2 x8 f6 l: T# L
, K y3 S8 r: ~; \) p) Y, l9 N virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;" M( ~& C0 H# f$ }7 U* p
virtual bool CheckAndRefresh() = 0;
' E; G$ w& P3 \ ]! r, a1 E virtual void StopAsyncFind() = 0;* G& w0 N/ p2 N+ d6 [$ F
virtual void DeletePorts() = 0; d" h; ~# h" h0 p3 I
virtual bool IsReady() = 0;0 Z0 {/ v1 z7 J* t# V3 V2 e7 _" e
virtual int GetImplementationID() = 0;
- d# D% m" z5 {* b8 A
0 h3 r0 J8 g; P7 } void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
' q* W% i* x$ I- G+ v" O1 e. p0 W& |
; G% l/ A1 h! I$ N$ U void SetMessageOnResult(HWND hWindow, UINT nMessageID);; i4 K: |+ y. O4 j v& i7 \5 H
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
, ~; p6 z" C& a; Q: j" }( J uint16 GetUsedTCPPort() { return m_nTCPPort; }
7 G' D/ m3 j/ ~. @( g: B% P uint16 GetUsedUDPPort() { return m_nUDPPort; }
5 Q+ P3 f/ ]! `' W1 o: P# }! }- K5 H. \" F/ }3 B2 i
; h: t3 e2 y, Q, S
// Implementation3 O7 `/ Y- G0 V# g. _, J
protected:" d( M! G, M `6 e0 ^
volatile TRISTATE m_bUPnPPortsForwarded;
3 R7 V/ l. e4 m6 ` S void SendResultMessage();
* u j d) E3 | uint16 m_nUDPPort;
' m1 @- P% I5 r- s; c$ c% Y. D uint16 m_nTCPPort;/ Y# J2 U2 ?* _0 p
uint16 m_nTCPWebPort;$ Q' h$ r7 T2 K0 y& y1 x' u$ s
bool m_bCheckAndRefresh;
6 k+ m4 t# I8 Y& j
) ? a7 I, o9 d
?1 L# G, Z" l% e2 \. @6 M' u* Rprivate:. y3 G4 u: O9 d! l% U
HWND m_hResultMessageWindow;& w# t4 p( M0 w) `5 x6 ~# A8 G
UINT m_nResultMessageID;
/ H/ M9 z7 E7 m% Q
0 g# R* S& _' s* W8 @3 c, g+ ~: }) a# N) u
};
% v* S0 F- W) N- @4 m1 S
3 A4 k6 K! E' T+ V. c. ]( ~9 s
, Q7 A& v8 ~) c7 }0 n$ [, w// Dummy Implementation to be used when no other implementation is available
' h( I2 M) { E/ b) wclass CUPnPImplNone: public CUPnPImpl
) ]* A6 A0 E9 M2 i+ Y* n* `{
+ [* g4 w6 E, Vpublic:
" i- G& x z0 I& K, ^ virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }; {) l) t3 k9 i( c
virtual bool CheckAndRefresh() { return false; }: H% y5 U) U' A) v6 g5 Q
virtual void StopAsyncFind() { }
9 q' A& e6 h" ?5 W$ t virtual void DeletePorts() { }4 C0 y1 g1 W/ |$ N! A
virtual bool IsReady() { return false; }
& I& r8 v$ P7 z" D4 k virtual int GetImplementationID() { return UPNP_IMPL_NONE; }% G1 Y5 J0 z2 D- k( y
};) U4 ~. d# h/ s2 F
5 O& v, S8 c4 \% L- M# c! L0 { V3 W9 C# _
/////////////////////////////////////
' Z! @. ]! y% G% R8 U. w9 l//下面是使用windows操作系统自带的UPNP功能的子类) s( ^ R" D" P: x3 v" }. y- m
; m7 \# q, }. Z/ ?# Z4 u! X+ Y9 |
7 l5 u( T9 A$ m( X+ [#pragma once5 L9 n. E W# {, u% c
#pragma warning( disable: 4355 )3 }: O8 x* p% Y6 ?: m/ ~5 I, |; m
& K4 u, ]* G3 x# ?
( Y6 ]0 N* y& X, n3 y; a6 R#include "UPnPImpl.h"
! N K) [" j8 n/ g- q5 ]. y, B#include <upnp.h>
2 T" Q6 i: R$ F1 a" Y6 S/ L#include <iphlpapi.h>% [. T D! P5 a& O: t
#include <comdef.h>
5 z# f" v% s8 L2 ~. E2 q#include <winsvc.h>" H6 P/ ^4 O3 e
+ J8 [5 c) R/ Q. x, J' o/ k
0 s5 a% H9 D) S#include <vector>7 L$ K* O) I; A) D5 v! M a
#include <exception>8 C2 |- w$ e, m% i* ]0 {& q- g7 {$ A8 }
#include <functional>6 `' A. k' R1 H2 Q! `% g
7 B' f5 B+ c* Q& k5 T, P/ X, p
; l: x# ~9 X" W" |( n9 P9 J. D' o) ~' P: u$ \3 G1 S* d1 ]8 F
( H: ~: [$ {) m0 u
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
" r: R( A3 s% z! O0 @* Htypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
. k9 f# o% a9 ftypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;4 B$ l1 H7 m; R$ H' C* K8 P
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;$ t9 o' n, S: A' }6 n+ C, r
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;9 f+ D- x# C6 O& F+ i# `$ W
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
H5 g L: e' u/ p" w1 W" k# `typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;& T1 H/ i; y0 f4 ~
# X3 n/ C5 k7 |+ q- B+ F. {; k: d+ a7 r8 D# ?0 ~5 Z
typedef DWORD (WINAPI* TGetBestInterface) (
: b# y4 l; u! y. [' v, | IPAddr dwDestAddr,
0 u4 P+ \; G f PDWORD pdwBestIfIndex8 ]8 A A) j/ l W2 N
);7 j9 a2 ~. U7 `
* }' H- I: J% i& s" c4 D2 J
: I* q6 b$ E( Ttypedef DWORD (WINAPI* TGetIpAddrTable) (
' Z: H# y( c5 i$ S2 t3 j, J PMIB_IPADDRTABLE pIpAddrTable,
8 i3 e2 L. M: b$ U( v PULONG pdwSize,
- d9 k2 @( U, M0 I u. H2 `# k1 A S BOOL bOrder
3 G {" T1 ~! B$ a);
) a, Y3 Z: i8 O" v
+ [: o" r$ u+ b$ D6 P2 O1 }: t6 [- [8 ^8 @9 T2 R7 w. u
typedef DWORD (WINAPI* TGetIfEntry) (
6 ]4 k/ V. s' {+ I PMIB_IFROW pIfRow/ f. U; }; t6 ^/ w" w3 o
);1 E* L) c' P# ~" F$ L1 w
0 Y# D; P% c4 \5 }( G
* D) z Z* p# rCString translateUPnPResult(HRESULT hr);
6 k/ S2 A- A+ pHRESULT UPnPMessage(HRESULT hr);
. e# m$ y& O' u1 Z6 i0 e* |2 V% q
- f% }: I9 _" h& W% q: e
class CUPnPImplWinServ: public CUPnPImpl
. @1 s) w! S% H6 h$ y2 Q5 w7 V{" m' A+ [+ K0 ?" q4 B. i7 E
friend class CDeviceFinderCallback;# r" z8 z3 n$ w! {5 g2 e. f2 C- A; D
friend class CServiceCallback;
$ Y) |- R- M. U) I( I* U2 C+ j% r// Construction
( A; d' N1 X L& d1 jpublic:
0 m/ W- |& S, {1 E% z/ r virtual ~CUPnPImplWinServ();
. ^6 N( a5 D$ g CUPnPImplWinServ();* c# C, B+ U, V1 y1 w4 r! t+ K6 r' j& R
( P, @# f8 ^1 g; }; J' [" t# `4 l2 @
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
0 m% F& i! F* t9 M& o, L6 d* E* q virtual void StopAsyncFind();+ q9 P9 n/ t( X
virtual void DeletePorts();' \) |! K" n4 J
virtual bool IsReady(); N: f9 s( v% Y' _/ T' o
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }- b5 I( y0 f* M5 A/ n. K
9 ` h- Z/ ~/ T
; d" H4 N5 G/ E2 b
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
& g0 e! g5 b! r5 x // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
) Q n; [5 X/ i$ a4 M& J virtual bool CheckAndRefresh() { return false; };
# n- \( o; o Q: [+ i) Z7 {5 A- Y
( v/ V6 a+ H( M" y
' h! S. e& y% S1 Sprotected: ?- U8 r) g. L
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
$ q' Y6 o' N: s9 f, p- u2 d void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);( f T1 v- t; X Q/ z# p
void RemoveDevice(CComBSTR bsUDN);
# e7 Y8 h: W: M6 x' Q bool OnSearchComplete();
8 ?7 \. U/ W) ?/ B y void Init();
: f& n8 d' O8 N R y; b& W
! ]( r* y- V; g+ b% Q- D
! Z+ r G- U* N; X! S( v& e inline bool IsAsyncFindRunning()
- x5 Y, m: U" H, {! n {
0 @) o d8 J) B3 A' W if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
* k7 G# E0 E3 m+ G& } {
1 Y9 a% _/ I$ g* r3 e7 V; E m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );* ?, B9 e6 L* N# b- R8 \# R6 n
m_bAsyncFindRunning = false;; K' H1 n( w5 A; e! Q
}
9 f. M% h. b4 I. S, O MSG msg;0 D; _7 E; {5 i/ a8 G# M
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ): l/ y- \8 m- L" r. y# U1 y
{
% F+ w: I2 z. J z4 w TranslateMessage( &msg );
5 L2 K6 L4 n6 c4 j6 [ DispatchMessage( &msg );) X# h1 x; q$ \! c8 A
}
+ X8 w1 i7 M$ }4 W' L H, h return m_bAsyncFindRunning;/ ]: ^% N7 l, R9 B/ A/ o. Z# K7 }* h
}5 L+ R0 X6 U' q& c: l) f6 X5 B
3 H! a! C4 Q0 v5 H' }' a3 X) v! E6 H
# E/ ^ g& u) m' q2 @0 | TRISTATE m_bUPnPDeviceConnected;
5 S% E2 e V: t: \
0 i3 S# i5 _9 K5 W6 A# Y
& c+ G' Z& ?# N+ [4 z# n// Implementation; N) T! O% R) Z5 @5 d
// API functions$ U. u+ N$ k: n1 g' e' g
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
" X/ z: v1 R3 V7 ?+ p SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
: K+ H, ~2 Q$ j$ j2 y4 d- C BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
! R6 O% j4 H" z, s BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);( ]" l' J, F5 H, h9 f/ R' k4 h5 [
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
) r% Z$ u1 `( O$ X4 ?' g) R BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
4 T6 s0 e1 M2 h. w
9 N E4 i8 J" t; V% }8 I- p; w# N9 }- ^) v. L
TGetBestInterface m_pfGetBestInterface; c0 }: A% ]- m! h" |2 ~
TGetIpAddrTable m_pfGetIpAddrTable;
4 T4 v/ R8 @: S& m, | TGetIfEntry m_pfGetIfEntry;: X7 P2 K7 D+ d' `% ~. w! n
! _; C) [# L, h2 I5 `2 b0 O
* n4 F9 q- g! g$ \. S" x! { static FinderPointer CreateFinderInstance();) r9 ^. j3 M+ L3 B" I1 U" Z
struct FindDevice : std::unary_function< DevicePointer, bool >
0 }( d& {$ r9 v7 ^7 r% j2 f {
; n4 W0 S) V* {6 e, A1 V1 |+ Z FindDevice(const CComBSTR& udn) : m_udn( udn ) {}# M; f& s! F1 H7 w; G7 r
result_type operator()(argument_type device) const
% T5 H6 ]: M+ u' u ^! W8 k4 c% ? {% N% I/ F. U4 b8 \
CComBSTR deviceName;2 L) Q$ o0 E! [. n, h( h6 r
HRESULT hr = device->get_UniqueDeviceName( &deviceName );: V* e8 @3 t6 D% F0 b
C6 Z7 J7 @# j0 v' ~
! Y- O+ Y8 y3 b3 h& C3 h
if ( FAILED( hr ) )
% f: I- p G& t L) Z8 P* k return UPnPMessage( hr ), false;
7 H: F2 f, n0 L K2 ^3 i, Q l, [* U- y8 m7 b# Y: G* Y
6 M( i$ y; | A- f7 { \ return wcscmp( deviceName.m_str, m_udn ) == 0;
J" i2 s7 J. A. V) O0 J* X4 s }
' ^( N2 I" `4 i" P( F. V CComBSTR m_udn;
+ f3 Z- o- Z ]' g6 `9 i( g# P };/ S! X+ }/ S/ {% P1 ~; X* H
% C9 C: |* j, {' e1 S
void ProcessAsyncFind(CComBSTR bsSearchType);
9 O& Y5 U# v% w! ?' m( O HRESULT GetDeviceServices(DevicePointer pDevice);
+ ^6 P/ u2 b* U: J" A% I void StartPortMapping();
1 ~$ \2 c. W: A; G HRESULT MapPort(const ServicePointer& service);5 V* V, ^9 ]. d- N/ l
void DeleteExistingPortMappings(ServicePointer pService);
K" |. q, I. k void CreatePortMappings(ServicePointer pService);8 t3 I+ U e3 O+ f t
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);6 {9 o. U; T. D0 O, k3 }& A
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
% y& Z; I+ B+ C; X& \/ T LPCTSTR pszInArgString, CString& strResult);0 P4 B# D' F" C J: E8 H5 d
void StopUPnPService();
: t7 u3 h# z* A5 d- u, w \% h/ P8 C* [3 k" b- d
1 \3 M% W X3 \
// Utility functions
6 O# [7 b0 O6 n) L* T4 k# d+ ] HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
; Q2 p2 ]9 H* T: c3 c0 v' v. \ INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
/ F# b: N# w9 j. S- |* W" } R. m INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
5 M( E! @0 @& I, u0 q void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
* \$ {9 T4 n( u$ X4 }- p, } HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound); I' }) `* r4 o; w% b
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
4 K# ]9 _! [3 [- ^! }+ O) f CString GetLocalRoutableIP(ServicePointer pService); d; B5 Z2 Z* {4 Z& h! D
4 L( ?6 |7 s" ^9 R5 q; N
' e0 p" Z Q8 @' ?3 l, C! S, i" X, o
// Private members4 u: O# }2 c2 Z
private:/ U0 T; v5 P: J" e
DWORD m_tLastEvent; // When the last event was received?
/ ^/ [% q& c* _5 v std::vector< DevicePointer > m_pDevices;
: \2 \% n) g/ H$ B5 ~$ ]( J& T std::vector< ServicePointer > m_pServices;
- y; C2 @1 u# _, { FinderPointer m_pDeviceFinder;
w" H. }: `) `2 {- W. |1 h DeviceFinderCallback m_pDeviceFinderCallback;
8 Y8 H2 H# u% Q$ _$ q+ U; l ServiceCallback m_pServiceCallback;) ]6 m1 D* {1 z' `! C0 t
0 R; t7 T) C7 U. N9 R* G" X* B0 @2 S, ^2 u
LONG m_nAsyncFindHandle;# m s, F# ^. D" S! c$ x5 D* q
bool m_bCOM;4 A. S9 Q, [/ P# y/ Q. V) V. {( \
bool m_bPortIsFree;' M, P, Y' c3 H! o5 w2 K& B
CString m_sLocalIP;
T3 I F3 C8 a& s% O! R% p CString m_sExternalIP;
1 z3 F1 e9 z; ?# } bool m_bADSL; // Is the device ADSL?
* K. {# ?7 F/ V- ]. K bool m_ADSLFailed; // Did port mapping failed for the ADSL device?0 b" J3 @) ^8 E. U
bool m_bInited;
5 F: o$ _- @/ r8 o0 B; b6 U bool m_bAsyncFindRunning;; J e* p9 J. o4 ?* c
HMODULE m_hADVAPI32_DLL;3 D0 P* l7 {% X- k8 V, \3 f# u% ]" V
HMODULE m_hIPHLPAPI_DLL;
% F% q& \+ Y7 h1 l bool m_bSecondTry;8 M1 d5 C% H+ @$ u) l1 w
bool m_bServiceStartedByEmule;5 f1 E0 U$ K$ ^; {6 V
bool m_bDisableWANIPSetup;4 ~1 _! @5 G {' W T, B! g0 K
bool m_bDisableWANPPPSetup;
L" M+ n# l( D; \( a" C! y. Y( C6 A4 g) d8 J9 V- T
# y0 \ I' |8 s& P y) y
};; k& \3 {. C, p, ~
( M( R( h% a+ ]3 b
4 @1 D0 Z3 G* B# B1 s// DeviceFinder Callback
1 H$ f: B3 ]1 t8 j# qclass CDeviceFinderCallback3 `$ K ~' Y! Z0 S" C, _/ q" G
: public IUPnPDeviceFinderCallback
& V1 n* x5 T6 T: g. V{2 y3 | A$ c6 M: j6 z! z7 M m: G
public:& M, [7 u$ Y# U+ [" ]! i
CDeviceFinderCallback(CUPnPImplWinServ& instance)
1 x+ s% ^2 R' D. U) E q* |) i) G g : m_instance( instance )+ @" h; r- ~5 O4 B9 ], N" ^
{ m_lRefCount = 0; }) H) L$ V5 R7 `& j9 ~
' @& |4 z( [# g, I. ~' R
# ~7 Z; E) v0 f' O, C; w* o STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
1 W: ^/ b4 z6 z' n7 l STDMETHODIMP_(ULONG) AddRef();
7 g. q0 l7 r0 n! g STDMETHODIMP_(ULONG) Release();# j. S. G7 ^# D0 j+ B5 L
; V: e; Z; f$ M# R
9 a/ P: x( @. e1 a2 W
// implementation( E5 v0 m3 Q9 `1 u# e! w* j
private:
- F, S" M6 i; ~; Q HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
8 C2 A# E* D, A; M; g- [$ v HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
H3 M5 J- I, q$ J# v HRESULT __stdcall SearchComplete(LONG nFindData);' i9 z& W3 Z2 ?- E
' Y. g" }& G2 E4 v8 J( l2 o6 l" x
private:
+ c: j1 q0 A- t w% V: k+ @ CUPnPImplWinServ& m_instance;
1 {9 Z# }+ p, }" i, k LONG m_lRefCount;; E1 I! z6 \, T
};6 v% Z* M' t6 u: u0 |' v
! n0 t- f4 w# d4 U8 |' G
8 m- l" u) j5 B6 c// Service Callback
4 P- Z5 j7 H, y) tclass CServiceCallback9 F2 h4 V/ O- P) S ]
: public IUPnPServiceCallback
% F# ]) i/ w1 A4 I. _{
L2 T4 V4 s8 \) m5 cpublic:
5 z# h' K! c) l( L CServiceCallback(CUPnPImplWinServ& instance)
" P' q4 X9 O7 A4 ?) m( T2 Q : m_instance( instance )
# V& D5 `) O8 K% ~ { m_lRefCount = 0; }! p% z% W) Y* K. E _& d# z7 P9 Q+ ]
6 Z) l6 b7 b9 I
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
5 T; q# K* w4 B" D$ _' \+ d STDMETHODIMP_(ULONG) AddRef();1 S, ?, ?6 ?1 S: \* d; o
STDMETHODIMP_(ULONG) Release();- W. T7 U4 p0 n ]' C/ A7 R
7 o6 ~$ a, K7 H: N' V) E
' ]5 E; T% G- ]/ s4 ~// implementation
' Z/ U/ I$ W3 z5 F8 J+ m- eprivate:
( L$ R- F+ o) H: D9 ?7 m' t1 j6 D HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
m1 ~. N) H2 q% C# H+ Z/ D HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);$ [% p" F% @% p' G" i ?. e
! q) @8 f2 y- H
$ o8 F" S8 E4 h- Bprivate:" e/ {9 v( d! ^' W- r* P3 d1 ]2 Z4 z
CUPnPImplWinServ& m_instance;
( a, O) O$ s: d# @+ D LONG m_lRefCount;
4 m. g) p5 [- T. v) }( m};
7 n9 K" ^% Y* Z! S3 m& q5 N( \; i" q+ y
- S& S, f' C( g/////////////////////////////////////////////////
; f7 q6 Z" M. r: O6 s Y3 d2 ^8 @2 M- W h
8 h5 k3 }$ C6 J使用时只需要使用抽象类的接口。
% N7 H1 Z+ U3 dCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
8 o) W$ S: O1 _" Y" ]7 Z, m8 _, @CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
, ]- u( O/ X$ u0 y: k) Z) |CUPnPImpl::StopAsyncFind停止设备查找.+ S. h! o6 ]/ @: D
CUPnPImpl::DeletePorts删除端口映射. |
|