|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,) C# }/ z4 p3 L; o
: b3 B! `3 B, a. Z
; ^; t0 u+ k3 M6 Z0 Z5 \
/////////////////////////////////////////// C' W( |" v5 a- H& l, q7 G0 q
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
" d# _1 G8 ]; }1 L/ } a$ m8 b# J/ F' T6 h0 {- X- r
: J( i* o$ G6 N
#pragma once* P3 K& Y3 d8 r! e- H) t
#include <exception>
3 u4 Y( n: v, ^
: O6 u L8 j3 S) k/ o. a0 m8 [0 ]1 Q2 S) |8 i7 O9 V! s
enum TRISTATE{: |2 [" r) H3 ]. a& P0 V ]
TRIS_FALSE,3 n4 A }! _. X" N
TRIS_UNKNOWN,
9 p$ R8 s! k9 k0 S- ~! Q- W+ V TRIS_TRUE
! z$ R6 F9 I% }* {, Z};
* X$ T6 J8 r- k1 M2 y3 v/ p* Y/ n/ w
+ i& y' W% Y( F: w5 b2 q( e8 ?+ C
enum UPNP_IMPLEMENTATION{; t) c/ V/ _% D4 P* ^- g
UPNP_IMPL_WINDOWSERVICE = 0,
2 m- C' _: z. i; o! p UPNP_IMPL_MINIUPNPLIB,
; r- ]) Z4 x: B/ ~1 m B UPNP_IMPL_NONE /*last*/% u/ V+ ~2 @. b4 l, ]( y
};$ P4 d4 _5 @( K' h5 Y
- T$ W0 q2 q* ^* A# `9 l: t; ^- y1 [* k H
/ A5 e+ x) {4 @3 H, o# x* M
# Z% ?" ]& u: [
class CUPnPImpl
# V; O# Q) A; x% w r; _& L{
; m7 V) k5 U5 r5 vpublic:; G# T. {; T* H3 ^- p; J8 Y
CUPnPImpl();
7 x2 M8 k1 k! z, c virtual ~CUPnPImpl();
! k7 x: Z3 |& x' X struct UPnPError : std::exception {};
9 u# @& u/ I3 D( B9 W W enum {
9 n3 {( S# j0 K+ m( D& U Y UPNP_OK,* F7 f6 j" y. m1 j0 W4 J
UPNP_FAILED,
2 e/ Z" u. G( m o$ I1 J UPNP_TIMEOUT1 _8 O5 c Z2 e* `: [2 {* o7 u
};
' f+ f& Q, e* T$ p q, G6 Z' Y! d
7 M& l. V8 ~2 u( a9 w virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;. |9 ^. `8 m( }; N2 z6 G0 i R
virtual bool CheckAndRefresh() = 0; I, o# d+ a# o( t8 L" T! P
virtual void StopAsyncFind() = 0;
8 i6 r' \& j# r% ` virtual void DeletePorts() = 0;
; d+ j' D. ?, F g+ Q8 t virtual bool IsReady() = 0;
2 P1 D" H: }# }9 a virtual int GetImplementationID() = 0;# p9 x( W5 i. B- n+ w" d
# D8 z+ z+ u: q9 Z( a' ~- W
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
4 g0 r6 O x" p' S, ~. v) O) B( {: O
2 ` F" v( O. _7 w9 \( ~ void SetMessageOnResult(HWND hWindow, UINT nMessageID);
- J/ E" t5 h7 F) b% `3 d TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }5 m# t' q' \, f# |' I, w
uint16 GetUsedTCPPort() { return m_nTCPPort; }, z. S3 _4 D8 {
uint16 GetUsedUDPPort() { return m_nUDPPort; } 8 P; b6 p) |0 g% ]# A
. v/ J9 C% F; W6 D3 z
3 h3 U% B) f& [' s% q* T+ R
// Implementation
: W# {! ?+ w; ], Rprotected:+ Y( F9 C o& C
volatile TRISTATE m_bUPnPPortsForwarded;
& u! f; v" z4 X; p9 a void SendResultMessage();
( G' W' V- ~" V* ? uint16 m_nUDPPort;
& X4 i5 D% K- ]* _! i' l uint16 m_nTCPPort;
# ?, `9 B5 u, |% o: {# o- S6 t uint16 m_nTCPWebPort;# |2 ~4 i9 o3 y9 C4 Q$ H& O0 Z/ D
bool m_bCheckAndRefresh;
: Y* t' J* f% h' ?5 H9 F
8 K# r/ S2 v5 q. U$ [, g' G
- x7 W) }- a7 o3 a: i5 C( yprivate:' p9 ?$ Y Y/ i; L* Q& y
HWND m_hResultMessageWindow;' f1 t4 p1 j0 ]4 g: O/ H" [! _( F
UINT m_nResultMessageID;
$ x. A, z; u( [* q
1 W! T; B, `6 X1 U- G6 ~1 v5 [" r# m0 n( y# X
};- E+ a: l9 i' ?9 w8 Q0 }3 W( ^& z: g) o
# g3 n7 c' O9 W( a! F' q- e' l: M7 \/ v1 I' o
// Dummy Implementation to be used when no other implementation is available
8 ^6 _4 w3 L% _/ dclass CUPnPImplNone: public CUPnPImpl
3 O5 j' H7 H6 t. I0 z b{5 y, K9 C" f, [. p$ h2 f
public:' J% s: P# H# `. U2 C0 Y6 P
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
7 j( u9 h9 L6 g8 J. V5 i# Q0 L virtual bool CheckAndRefresh() { return false; }0 W. N- `% C( g6 `6 S# |: |
virtual void StopAsyncFind() { }: ^, t& y% V" |$ B
virtual void DeletePorts() { }9 K8 ?7 H( _3 Z5 G; N
virtual bool IsReady() { return false; }
0 X% L7 \6 X; q( @ virtual int GetImplementationID() { return UPNP_IMPL_NONE; }% k6 w8 P+ ^: ^; B7 h0 J# p( U# c
};5 ^2 m3 M0 @- K! d9 U
" X8 Z4 N8 ~& J& V' b- c9 p
; G$ z$ x6 K# I! P$ j0 a4 ~: a/////////////////////////////////////
/ B1 M x( S/ q3 H8 r; v//下面是使用windows操作系统自带的UPNP功能的子类
0 B- j9 X6 u8 ]% E1 f9 N( a
$ j# Z% l$ v5 o) I$ g U
. H7 |/ H2 S) K! Y- |! ?#pragma once+ S6 X. @- E4 U z$ v/ v
#pragma warning( disable: 4355 )+ S d& H4 D0 S) {3 Y' U% j
9 V, j+ g; o% I
% y: G2 Y* w/ w/ e
#include "UPnPImpl.h", O+ @3 {& P2 E
#include <upnp.h>
5 [+ l' L2 m8 V: z' s#include <iphlpapi.h>
! L; t/ F( d- `" k+ m! s! ]#include <comdef.h>
2 [: [; {/ L3 R/ _6 V/ P#include <winsvc.h>. [ l: u3 a+ H
% ^- {6 y5 S* {) {7 A7 b
+ x% f4 b8 ^6 n: b% ?7 |#include <vector>
. p3 z! J% B/ \- L/ T- {+ g1 k#include <exception>
D% D0 V7 C7 F! d3 M" O#include <functional> D3 O0 a0 j# F
7 m8 `9 J# ]% [- S3 b. {
9 g( e h# z m( r9 n
@ P; J- N. S) Q: g* q7 A) v2 T* p! G* `* z) |* A
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;% w7 r( ^, g: q' T, | I" s/ B- d
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;4 K9 r) E: K# j; W. ~
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
8 R( o' P7 H! p% J, h+ v( k- ytypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;, }% w9 u! w1 u0 ^2 v. H
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;7 |& |- b2 n8 R1 i- |1 M9 L% }
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;1 I- H* H( P" S& x8 X3 U
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
; j* b4 S3 w5 `% x- v9 {
3 r% K+ E" o& P5 y+ H/ e0 H6 h% u
/ g# Z2 N: p9 n L6 c, v. b" k( p6 mtypedef DWORD (WINAPI* TGetBestInterface) (
, M1 R* C6 B/ ^6 u5 U IPAddr dwDestAddr,
4 F9 J* I2 u- X& Q4 |% G PDWORD pdwBestIfIndex% Q5 t. h y+ b j* s) r# ~& L; W0 P
);
4 A# p: j) B( \7 ^4 J) X! A% ]! P. C) A; `
( j9 ^; J) s6 L. _/ [
typedef DWORD (WINAPI* TGetIpAddrTable) (
* ]/ K0 B/ y* T PMIB_IPADDRTABLE pIpAddrTable,
; P1 P! O$ M/ Z& K, n) M1 f PULONG pdwSize,8 q3 Y g8 R, I5 Q- i @5 B
BOOL bOrder- _* U0 W1 u# d C3 V
);
! N2 Q2 w+ y& \* T5 J8 y- e' ~+ T! |3 h l2 v) [3 G
4 a6 }3 P2 U4 F& n$ X! @8 @typedef DWORD (WINAPI* TGetIfEntry) (
6 F9 N8 j( m# K7 x' } PMIB_IFROW pIfRow
9 \8 p/ w! Y2 s( M9 U b+ Q- P: F); O( L# S0 f! S% c, B+ i
. X8 H& A* N8 C
& A9 \, N7 y3 @2 w6 {! l0 _# V3 oCString translateUPnPResult(HRESULT hr);
" |4 M% v( S8 Q( T/ L2 v2 DHRESULT UPnPMessage(HRESULT hr);
- N: a- a3 G$ H: P' h J
( x$ H; i( m% `) P5 W5 [( p# D( Y7 j- ?* I6 V
class CUPnPImplWinServ: public CUPnPImpl
I4 \6 `8 E! r4 E{: u5 C8 ~0 D" o" e+ ]! D3 e+ O- `5 Y
friend class CDeviceFinderCallback;
9 P. u) t- L" t5 k, E friend class CServiceCallback;
) p; I' n& D f; |+ O O// Construction' l1 Y# e9 q! b$ u5 ?* L# M
public:. X! X2 |( ]( n( P @$ G3 I6 I4 z
virtual ~CUPnPImplWinServ();7 o8 b8 m5 h: O# K' |
CUPnPImplWinServ();. f' O( C$ T A6 y" `; f
* F4 b5 {% O+ P1 j. j! q) N/ ^4 p$ X9 g) \ E6 r7 K
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
O% C% g4 E; O. N! W virtual void StopAsyncFind();' Y0 G* B+ {1 ^& D( W5 ~
virtual void DeletePorts();
$ x$ h7 M9 o$ M( p8 m6 Z1 a virtual bool IsReady();! w; Z* T( C. b5 P% c
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
" A2 e0 e5 w- t( G% |6 ?; @, z' R4 N& F6 J5 o) l7 N
' N: q7 m) Q* M3 h$ H/ L t+ a // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)4 H ]5 O5 m! J: c2 x. b
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later; z; F) ~3 n0 ?2 n% V" P
virtual bool CheckAndRefresh() { return false; };! O2 r2 W2 u1 G" i2 o
5 @8 U- k; I7 m! Z: z
& p: j6 g! f9 Z, |- |) kprotected:% T; [. | M: ]5 I3 V0 |) P" }7 C
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
- U( I7 T. R; L: `- C void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);; S6 h; A* S: t. x! m" n, s
void RemoveDevice(CComBSTR bsUDN);
3 n9 X0 z; v7 v1 H+ M i bool OnSearchComplete();
7 V3 ?* W4 O5 k6 U& [/ C% i void Init();! ?% f; p6 G( j; w2 c4 L
: `3 F; G0 v- s$ H
7 N5 M( {$ [/ e9 C1 g, ^, @ inline bool IsAsyncFindRunning()
/ z5 ?+ l8 Z9 {( U2 X) n4 Y {1 Z/ ^# U9 i5 y0 D. ~8 K$ ^
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
7 w9 y8 f0 i) X. k- x) Y& r# V {
3 }: V1 Z0 v3 A% [ ^: c! m/ u m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
( r! s+ P4 ~- `+ S+ W2 e; \ m_bAsyncFindRunning = false;
5 b" N5 I4 B& j7 p% |; ~0 E }1 l6 `0 W: x9 |1 m" B [
MSG msg;8 ` v G$ x, C# H* E0 T
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
" _. }, v0 e/ n6 t {
: j3 s" }, N ]( r TranslateMessage( &msg );+ g. \8 V1 k0 }$ _* P( S3 S
DispatchMessage( &msg );; s+ x4 _* H$ e" [
}
8 \" f1 R, G6 j$ d+ d: y% { return m_bAsyncFindRunning;
( R9 G0 d+ a) v" ~) ~ }2 {2 p6 K% p0 o/ M$ I* x) B
6 M" U2 h( T5 d0 e0 K, C
( `, W! R' D; C$ [ TRISTATE m_bUPnPDeviceConnected;6 O1 A' n: Z) U7 v: A0 k# j: g& Q
7 n- J7 u' m! W4 @3 c! w" y3 }
1 c1 u$ u& W! b// Implementation; H' }1 ?) K0 U, T* }, W7 I' v( C! f
// API functions0 p; f- _- e7 H! h/ e
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);3 ~; K! U; _3 s
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);' V ]4 s2 g! ?9 d" h3 n9 x* Y7 B
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
8 @. p' j" t% d- ~# w2 y; d BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
% h2 ]) d& h3 m) X+ b% V1 C; K BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
+ @) C& r8 {8 e: P G BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);, m C. ~1 R2 r5 P6 @
; ?/ t: L! B* m, T
1 M8 x+ r% |9 W TGetBestInterface m_pfGetBestInterface;$ d8 a9 {2 x k6 Z1 o
TGetIpAddrTable m_pfGetIpAddrTable;
6 C; g$ |- K& c4 y TGetIfEntry m_pfGetIfEntry;
w' {1 h3 _4 v+ ?. e' \9 u* M% P" H( j5 a2 G
0 l' H# D* |6 t- t; n static FinderPointer CreateFinderInstance();! z- F! O0 i% C6 p- p1 M$ z) Y9 w- N
struct FindDevice : std::unary_function< DevicePointer, bool >6 s. L4 |% s" I+ M
{# a. v0 ]7 d/ Q; [0 y
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}3 V3 c+ ?. n2 _0 ]
result_type operator()(argument_type device) const9 |+ Q& n' H3 w( x. O
{
" T# a' E$ E$ P+ ~5 i CComBSTR deviceName;
. W0 _- H1 s) i4 e+ T5 I, ~! G HRESULT hr = device->get_UniqueDeviceName( &deviceName );
0 [7 i2 V' ?# r3 m/ f2 c
4 B. Q" @* n; _/ n/ D, H# S" R
% @0 H- S K7 |' H if ( FAILED( hr ) )
/ q1 C& p4 G h; |8 u return UPnPMessage( hr ), false;, i. M* d* Y. b0 ~+ b
6 F4 q( K1 T0 \5 f g7 T+ o4 G
0 r9 ~/ c% A+ R7 T return wcscmp( deviceName.m_str, m_udn ) == 0;
3 I! Q! ^2 @' P" T# D: z }
% [; q9 ^# v- I4 }2 @! F E8 N CComBSTR m_udn;
- z: Y( P' Q! ]% V1 R5 w/ s };; F! v' }9 Q4 {& z; q
) |& T" T+ E/ v" ] void ProcessAsyncFind(CComBSTR bsSearchType);
+ ]5 T3 u W7 T0 f2 ~ HRESULT GetDeviceServices(DevicePointer pDevice);& A* I* Q; d- Y$ R ~
void StartPortMapping();3 a5 g9 U* s/ V! |7 S0 J$ P; E2 \
HRESULT MapPort(const ServicePointer& service);
" W6 N U2 ` O8 m* |( V void DeleteExistingPortMappings(ServicePointer pService);( L3 l; ?1 `6 F
void CreatePortMappings(ServicePointer pService);+ l" A. R% \' @& F p
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);5 ?2 U- \* t8 `4 Z5 z
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 1 U* T0 n8 e: t9 W
LPCTSTR pszInArgString, CString& strResult);
8 Q' N: V6 B. y- S% { void StopUPnPService();' R( a! {% g3 o) l- h; ]6 m
4 b! c! A" [( j, `# t4 \+ w1 s K4 \# Y$ L( H/ c
// Utility functions3 W5 Q2 x. }' | |( E: U1 W
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);' j0 Q: C9 I; d8 Q1 B6 i
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
1 R, @$ w G; [: u INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);! e( g' g m2 {+ B) I
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);( }! ~" Q% P5 J3 m& I: p% ]7 w8 u g- `
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);1 H8 w( o2 X5 u
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);, X/ B: k3 |- A0 l
CString GetLocalRoutableIP(ServicePointer pService);
; D! X5 h- L1 x3 b
2 g. J! S3 W! B! w- K2 b" E( r3 }- l, r1 A! n! M x/ S [
// Private members. n/ F2 G$ v: I. m) W: X% _9 ?5 e8 ]
private:
: j# L/ F- N8 D0 @1 V9 } DWORD m_tLastEvent; // When the last event was received?
4 k. S0 @0 y4 H std::vector< DevicePointer > m_pDevices;
" E; G m9 d: ]. {' T( b std::vector< ServicePointer > m_pServices;
4 [6 F1 Y7 W5 z1 ~- A) N* Q% v2 A* t FinderPointer m_pDeviceFinder;: s1 J) C- b$ p1 }( N9 ~
DeviceFinderCallback m_pDeviceFinderCallback;% M& }% F3 _/ @
ServiceCallback m_pServiceCallback;: g" x4 I) P7 i% C
# h5 g: i6 A. `, E' H; B! q" p/ n9 ?9 \& w3 Y V
LONG m_nAsyncFindHandle;8 O' ~- {6 p* L' [+ ~4 I/ D& A
bool m_bCOM;2 ]" T- N1 R5 m1 k5 m% w$ u
bool m_bPortIsFree;
# [( b! A- ?( U2 Q& D0 j CString m_sLocalIP;/ y8 G, x) k; H5 }5 G2 O* A
CString m_sExternalIP;
- C! f/ p3 K5 Y: G3 x8 t0 R bool m_bADSL; // Is the device ADSL?" c. w6 W" k9 ~! H n6 E
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
6 F" R; B# ^ g4 F7 @ bool m_bInited;
4 O! e' _7 p! y8 i6 ] bool m_bAsyncFindRunning;: ]: E" {! a% g# }/ s/ [
HMODULE m_hADVAPI32_DLL;, P# s# ^5 N0 g
HMODULE m_hIPHLPAPI_DLL;+ P3 t3 _7 _; Q9 `
bool m_bSecondTry;
( m/ j% }4 w2 `) W$ ~ bool m_bServiceStartedByEmule;& X! v5 D$ `1 O# K! l! j
bool m_bDisableWANIPSetup;
1 B* ? N) z6 x' o bool m_bDisableWANPPPSetup;/ d. p/ h0 i, W) ?9 T: h+ O
) c% x: U6 p+ w6 p6 O- Z
0 W* B( q0 j0 @( l' I0 C1 p};
+ ? e8 @ K& ]% v! r0 E
; A6 P8 C& l! Z2 j0 x5 g2 G0 l( u6 {8 h# e( a
// DeviceFinder Callback
/ N' s8 l x- J: Z: Zclass CDeviceFinderCallback
# Q7 v" y/ d' C) B6 A) V9 |8 A : public IUPnPDeviceFinderCallback
2 E0 G/ _ f9 W2 K8 n+ A{# ~: o3 n: _/ n2 c
public:" N8 B2 I& r( c* n, O" a5 K( {
CDeviceFinderCallback(CUPnPImplWinServ& instance)
$ _( T& v# I/ Z' g : m_instance( instance )
d( n7 |( |) O { m_lRefCount = 0; }
' Q, Z$ A- P) A0 y
# [+ x7 s+ s3 F6 [. J( w% |1 \1 G, s; E) o7 }' h; T
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);& c! R3 j: u$ d! P* `
STDMETHODIMP_(ULONG) AddRef();, t: Y+ H, O7 @; j7 M
STDMETHODIMP_(ULONG) Release();
% h: X! U! m- N7 x7 K% m. V( K: u% k. g$ {" Y) K
& G2 o% x9 P9 z
// implementation
% ~& w5 s! L5 g; ?% Sprivate:
* R: ?% X4 _8 h; b) p HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);& ]; @$ ~. ?1 M4 {: F; h4 n
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);3 _5 Q2 n0 v2 f% p
HRESULT __stdcall SearchComplete(LONG nFindData);: m# a0 H% I4 [5 j& g4 ?1 w' q
# Q: f$ p7 R8 i4 @# K7 j
# `, {+ U* P" t% S
private:: U/ i- b" b, d* f0 s4 c& ^, e' r
CUPnPImplWinServ& m_instance;
5 m/ n; A; ~1 x- E2 P LONG m_lRefCount;- K. O0 k- r+ j& @, v
};" g/ T# @- k" T4 {* S
6 ]" \6 f. s" u7 Z$ g" ^2 W# h4 x, i
// Service Callback
' f3 f* O4 u$ f' vclass CServiceCallback
) [1 @9 z( j5 B8 |, u4 C2 U0 j : public IUPnPServiceCallback) x2 R! H l5 C4 V1 L6 E5 P
{( v2 G. t$ {- P
public:+ m4 B% H1 R; Q
CServiceCallback(CUPnPImplWinServ& instance), X- N1 b) o0 _9 I: b
: m_instance( instance )1 u2 N, ]8 \$ s6 Q
{ m_lRefCount = 0; }( @& M& A! n' o' \2 f
$ J5 [: ^( g, I& u
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);& S% M; M8 d8 d
STDMETHODIMP_(ULONG) AddRef();
( K- l$ S1 _0 c STDMETHODIMP_(ULONG) Release();
! ^) G% N) g, M* M" p+ B8 Z0 n% W2 [( [% `( \7 Y! D! _
2 v( v4 Z0 k: J K$ j4 X9 L- Y// implementation
! E" e% u. S Q2 [0 Y' a) Hprivate:
8 c: `9 n$ m; s' m HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);6 ^) b. ^% P. E6 w* U
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
" e3 G2 z4 d6 w0 ?+ l8 J; i* t( f2 C
; m8 P$ @9 k+ H( r+ Q* B% @private:4 D* n$ O6 V1 Y
CUPnPImplWinServ& m_instance;, r: r' T1 t7 n7 y/ J
LONG m_lRefCount;/ ]3 b7 h6 d* }8 v
};
( {! N# ~/ t8 Q' ~$ \: G
5 ]8 ]" ~6 |+ U1 }$ n6 I
2 R% j* S7 ]. _( Q' J2 {, } e5 U/////////////////////////////////////////////////( \+ u3 D, w% C' ^5 u) J$ ?
, u& v6 `4 F A2 k& s0 I9 ~, F2 B: Q: J
使用时只需要使用抽象类的接口。/ s' l2 u# H+ V, f7 h( R$ z+ g
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
3 H6 o6 P t1 j: wCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
$ k9 a6 s5 l4 G! Y9 u- HCUPnPImpl::StopAsyncFind停止设备查找.! t9 j- V% [" S8 M
CUPnPImpl::DeletePorts删除端口映射. |
|