|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
3 ~) m3 [. h) f m& D
: P- O& s' {5 g4 T! W' U `0 h: ?) i( g1 D1 p0 n* z9 v5 P( f
///////////////////////////////////////////
7 D7 E p' V' N/ l* X2 Y6 q# l5 q//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能./ J5 @: d8 n3 }
% n4 ~* ]$ m3 R0 P- s2 ^
9 n& w0 a! D. v2 M% w! d
#pragma once
Y) G$ I5 K' l( E$ G) e#include <exception>
. R* a% D {1 ~. z1 `
! v. Q0 U" B; `% }3 r) Z
+ b4 F* Q1 h6 s& r% p: W enum TRISTATE{
$ ]* a1 D9 @& ?! J, X) E1 A+ q TRIS_FALSE,
7 u$ D, {) U' l$ T1 J TRIS_UNKNOWN,( b4 A0 r9 ]( ?3 B8 g
TRIS_TRUE3 q" F6 X6 t6 d0 F
};* o& y! M' t( M2 N9 v7 ?
; p3 R# E F( _7 b3 H, b1 v
: m( g9 h; H3 S/ Z4 d
enum UPNP_IMPLEMENTATION{' w8 {4 K6 w, a) u1 L: Y7 o
UPNP_IMPL_WINDOWSERVICE = 0,
4 I, c1 J! _( D& L* v UPNP_IMPL_MINIUPNPLIB,
7 ?! j! z4 P. }3 t+ K9 E UPNP_IMPL_NONE /*last*/
6 U7 y* v8 o1 v R};/ m: e' C) U7 q7 P; I, r
" a3 D; W" l3 c M/ o6 x7 E* s# Z" m6 m: T
$ _1 G" l( R8 }' n( L+ {0 y$ J8 G0 r/ B7 l6 L$ R6 W* \3 b7 X
class CUPnPImpl* p$ K6 E7 |4 \( a- b5 T+ L- e
{, R& E8 G9 ]; z- I9 u, m' Y
public:
1 _3 ?3 A- X) f) i3 l* L CUPnPImpl();
; U/ h& B4 [+ P$ Y9 V virtual ~CUPnPImpl();8 n& |2 }3 O0 E+ }; f. q- G
struct UPnPError : std::exception {};
! z. e0 s8 f4 T! y enum {
+ v- ]0 Z2 V3 [" l: {0 [' u7 r UPNP_OK,; y! `0 L/ D" W$ _
UPNP_FAILED,, v! [9 ^0 `% P2 @& }- R8 ~; u
UPNP_TIMEOUT" C- K4 D+ S G: q! L" w
};4 r. B8 A+ q- ]" j& ^) I% S' C
3 S1 A* s8 F% s9 _, N8 Y f6 e ]6 ~) m
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
" J8 D; i5 H3 z$ w virtual bool CheckAndRefresh() = 0;. C5 ?8 P# h* d2 Z* e" w* v! ]
virtual void StopAsyncFind() = 0;6 T2 J b+ Y% B$ I: S4 b
virtual void DeletePorts() = 0;
; f- D; S$ l% H3 I8 u$ W virtual bool IsReady() = 0;/ j" }$ p9 v: t5 {4 U( Y1 P
virtual int GetImplementationID() = 0;) _6 y: a. |8 k. @ _
- Q/ C& r# o9 ?7 p9 W" s
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
$ _, T* S# n$ j4 l1 [6 e
' S) S9 y: P% g
4 e- r; W l7 i" I2 D4 g. e void SetMessageOnResult(HWND hWindow, UINT nMessageID);
" F ~8 H; B+ S$ y TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }8 v" S" E9 J0 y( d" _
uint16 GetUsedTCPPort() { return m_nTCPPort; }
9 `9 X2 y1 g& G: q uint16 GetUsedUDPPort() { return m_nUDPPort; }
' Y( i: S+ p5 N! n
1 o# x: T! D* _3 x: B3 ~' a/ w* ]( `( j8 l- `) J2 i2 Z! J
// Implementation: T: t# F& D% n6 P* z: K
protected:7 t% m8 j3 `/ j3 w8 B* \% ^3 Y& `
volatile TRISTATE m_bUPnPPortsForwarded;/ c4 B* b6 ]! d/ l3 v7 u) A
void SendResultMessage();
% p: v4 f) Q2 ~0 [; r) C uint16 m_nUDPPort;
9 K8 l% ~2 S6 k4 v% b$ I+ w" h uint16 m_nTCPPort;
, R5 H8 E4 D. c1 v* ] X uint16 m_nTCPWebPort;% l, }5 F1 j6 n- u9 z
bool m_bCheckAndRefresh; Z% L# K- h# \6 ]& X( |- \9 D. j8 n
" J. R1 \% Z" m6 f! ^7 U9 \5 F% t) L1 }, w" h/ I
private:$ f) b+ ]! r% N2 `0 N
HWND m_hResultMessageWindow;
: [) k8 i. Y. a5 e" g% e/ z UINT m_nResultMessageID;: c+ F# [8 n+ d, k8 j0 G+ \
9 b6 l7 v }+ o2 E; O
2 I" A4 [- N" ^0 M& s' {, Q* `- x};2 e/ [5 n- H$ T5 N/ ?1 k1 b6 Q& Q
1 j$ r9 N+ s7 w! A& G
+ h" m2 C, z/ m% G+ M// Dummy Implementation to be used when no other implementation is available) T8 k! v2 o/ ?- X; \, e0 g0 K6 X
class CUPnPImplNone: public CUPnPImpl7 `4 ^* n% q- }/ q' W0 e
{
6 ?- M5 \ b% k' I7 T' G @+ F6 Vpublic:
* O/ M% A* ?5 @ I$ }# |/ S9 v virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }9 ]6 `3 M6 N( x, ~# [$ P. _8 c( T
virtual bool CheckAndRefresh() { return false; }6 s" _ C/ U6 a4 n! E
virtual void StopAsyncFind() { }7 Z$ G; k& N2 Z3 q2 P- H" v
virtual void DeletePorts() { }' A+ y8 k: `# p( ]# I
virtual bool IsReady() { return false; }
* u9 H) J5 o' y1 h, T virtual int GetImplementationID() { return UPNP_IMPL_NONE; }% H$ Y1 s1 ? x! \1 J1 V
};$ x+ a) [* E, N' p* q4 f
3 G0 H# P. @# E( G) S3 m) D; ]+ O2 a* J0 ^
/////////////////////////////////////
$ F* l- `( Q. t( r9 D//下面是使用windows操作系统自带的UPNP功能的子类
5 F- I6 ?% ^# x; M2 R' }
2 [7 s" C3 F9 f+ }+ v: x5 }7 w2 {2 J2 b7 @
#pragma once
' x Q3 I* ?. F$ U! y& u* h#pragma warning( disable: 4355 )
4 O8 \( d7 w7 Y7 t# p1 y7 y5 ?' e& t3 w
& Y3 X' `5 h3 _# \- o/ b
#include "UPnPImpl.h"
& f% i. H* F* i4 a4 s#include <upnp.h>; `9 N( C+ C7 b" A3 [' r2 o
#include <iphlpapi.h>
3 s; m( v% D5 B1 P; a) E#include <comdef.h>
; @) e i* J3 B5 P#include <winsvc.h>, n( ^* N$ ]! J p
1 z2 O$ E* V9 z( g/ [
7 _$ R* ]; _: \ d) X#include <vector>
$ u. ^* R# ^* F& e8 {1 H& P- G c8 y#include <exception>9 l& P6 n& |3 @9 f7 C0 k
#include <functional>' y1 H, {9 _) {* z9 C
: ~% d1 _4 f" c) s, A* p! c7 w7 G" D- A2 |. R( y9 ]0 ~
/ p& E, m2 l: S" ~1 y
' c, h% g+ _7 A' D6 Utypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;1 e Z3 f1 t: z0 d
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;) R, u- c5 X4 C$ _+ i. U
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
* C z0 i) \- E$ X# atypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;# Y) v. k d2 C! G& |* D; a# v
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
& @' Y! h0 @% D* G( A C: ^. _0 Ytypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
( \" p0 M0 R& ~) k+ ^+ mtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;1 a3 P' I- D: j/ i
4 D, G3 J3 x3 v1 q9 c$ ~ z( t, Y5 H3 x8 d
typedef DWORD (WINAPI* TGetBestInterface) (5 k: Y; `! P% n2 K5 N& ~
IPAddr dwDestAddr,
6 V/ i; q5 b+ ?0 f: l PDWORD pdwBestIfIndex/ M9 U( u. D. S" }: c3 U, }, T9 H
);, a% |% Q# N# T- t9 O* a* f
, y" j1 B" m$ i" U& {) } X9 o" q. C6 v. x" h6 X7 d* N
typedef DWORD (WINAPI* TGetIpAddrTable) (
' w! ?, L) O) a; b6 Q0 X+ I2 Y( O5 G PMIB_IPADDRTABLE pIpAddrTable,
. m0 f" u" l- f) ]0 I% L% ], u: Z PULONG pdwSize," n" q, _( E! h2 b' s5 V! _5 W. y
BOOL bOrder# s1 S- v* x, B, G# y
);9 j6 _0 }! E, Z9 `. l
% c. e: I: p1 R
; y9 ^8 k5 n% N8 r4 L$ Ltypedef DWORD (WINAPI* TGetIfEntry) (
5 h+ b: O& [; F; {9 o PMIB_IFROW pIfRow
; u+ u, |- c2 i( D8 }" H);
2 k1 ]1 J- N# w7 M! R" m" X8 t2 E( O& L; b1 u' Y
& e1 y: s3 X2 l E( FCString translateUPnPResult(HRESULT hr);
* i7 }6 q3 N* @4 ]! J u- bHRESULT UPnPMessage(HRESULT hr);6 H, h0 Q8 F/ y. _" k+ U. J+ Q2 _
# S, N7 t# d0 K: K! ^: }
6 H/ d1 c. a1 n; P) D! m
class CUPnPImplWinServ: public CUPnPImpl
) |! }4 m8 P$ q i+ Z) _{, m5 j u8 x J- w( {- a* L7 v$ _
friend class CDeviceFinderCallback;
7 V; l: X) h$ A% g2 v" ` friend class CServiceCallback;
, a* c! f" Z3 p0 N; L// Construction- G- C8 C) q( A# W- }, @5 w3 I
public:3 J# x7 |- }* G6 C
virtual ~CUPnPImplWinServ();
/ k( a+ S: ^; r. J" {' K( S CUPnPImplWinServ();4 u! s: H$ \& c/ @" G4 O! d( x& @
/ X9 m! d) h& ~# h$ |3 N. U! d
6 p5 J/ @/ T1 ?2 F3 v7 [ virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }' d0 |( \6 W2 c+ E+ z
virtual void StopAsyncFind();& X+ ^( ]% A4 s( ~8 T$ X% C
virtual void DeletePorts();8 S3 ^9 K- d# [
virtual bool IsReady();
6 T; f8 b4 i2 d, N2 ?7 W5 o virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }3 @+ V2 }/ i% Y; O2 _7 {
9 w+ H4 e0 L/ b5 ^9 c' v7 ~
# v* x k/ q- R( U/ b4 s* D# u% B // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)3 U8 N, @7 p- P, D4 D3 C' g* v
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
& i& _+ v8 |( ?2 @ J virtual bool CheckAndRefresh() { return false; };" x4 E( b. \" i5 b( L' V8 r
) O( ~$ D7 T8 j6 ?4 B! a+ p
% q; d$ p6 r2 J6 a% Q! |; Zprotected:7 ?) @# R& ~, q0 G
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);) f6 N3 Y( Y2 X' M& J* q
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
% m+ o. v$ O0 W3 p void RemoveDevice(CComBSTR bsUDN);" p2 D: O4 D+ r4 E( Z
bool OnSearchComplete();( v8 }9 `# z+ C J
void Init();
3 K( h. D4 |; t2 k& I
" b0 ?" `# L" N0 R# f7 Y* P: v7 I7 K V0 M- f: H8 [/ p% v' Q' A
inline bool IsAsyncFindRunning() $ C' j* |) N- D5 `" Y+ n
{9 @* {3 }& P- [; p' ~
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )/ q3 I2 r O g. r
{, n& n8 T6 C' H6 E3 _
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle ); l, e7 U6 R& X5 ~) z; {6 D
m_bAsyncFindRunning = false;
' v! _, V. a$ Q8 N }
$ |' ]6 u1 T# _2 w2 n9 j5 e MSG msg;. |1 |# W, R. u4 B
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
+ W* |/ v9 X+ U0 G {8 s8 `/ y1 ?$ o2 X# s/ b+ O
TranslateMessage( &msg );+ t/ s0 z6 _5 c
DispatchMessage( &msg );, x! J' R# X( I0 h. P
}. h0 H( Y+ d) r! D4 \
return m_bAsyncFindRunning;3 i) E% _6 q$ m! x9 N) c& T p4 {
}% }8 _- J4 v4 z# a- |
+ \( ]& c* A5 Q/ h0 z7 a, |# p
# N0 d7 E) E, b7 v7 F, ^ TRISTATE m_bUPnPDeviceConnected;
- a1 v% Y1 n% Y0 u: }& d* D; J/ {6 T9 n* E& Y
: D! j6 {0 i& w
// Implementation8 q" l0 _; o3 H( }. R- t
// API functions
4 ~& m/ ~% T# m) @ SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
7 Q" g; S. y3 _- _8 u9 b6 z/ V SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
% j1 ]& l, T7 p$ w$ ]/ T' @' G BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD); L7 I; |7 S8 _8 T8 `( M1 W1 J
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);9 V7 r6 f+ P% J, B- Q
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
$ K8 ?& j/ g4 _' O2 P0 z& f BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);; t. X6 ?6 x2 p( S. _. N. @
) \1 g% W g2 B i5 ^
' H, N# \! C; B
TGetBestInterface m_pfGetBestInterface;
: i1 U, S, t2 { TGetIpAddrTable m_pfGetIpAddrTable;, N+ x! R! N, }7 Q$ |* ?( t1 X
TGetIfEntry m_pfGetIfEntry;
) P: m5 x# ~9 A) r
. N! g1 X f$ |/ W
0 {4 Q, p" Y/ Z3 ?- \ static FinderPointer CreateFinderInstance();3 o8 c2 ~' u* S& y; }( m
struct FindDevice : std::unary_function< DevicePointer, bool >+ D; u+ b7 h% l; V/ t5 v1 U& @
{$ ]0 |' s* K g
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
5 Y% z: k5 D; {& {6 h result_type operator()(argument_type device) const
% Q# [* b5 @, d, y5 J/ u* H { V7 g- S2 {! i/ x/ v6 A( k: C5 T
CComBSTR deviceName;" K1 n# X0 S! }
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
4 Y( A9 p# `3 e' w: X* I5 N- _. Q! Z8 `0 T! p9 Z9 o4 w" S' k
/ j% a: } C8 |% |
if ( FAILED( hr ) )/ n( q3 ?" ~) i. x/ Z: N
return UPnPMessage( hr ), false;
, c4 e% e/ H, d8 r( Y0 D$ y% Z U6 j# x3 i+ n8 ~% M
5 [' W b3 P9 e. j return wcscmp( deviceName.m_str, m_udn ) == 0;' v0 U* [ i5 _
}$ Z, T: t; n. g
CComBSTR m_udn;
% q: c, n5 X# H, X3 P9 G3 p };
}5 F0 b9 ~: i/ m
7 i5 V! \8 ^ l4 w9 v% ^) L Z/ v void ProcessAsyncFind(CComBSTR bsSearchType);
/ O* x, m7 }0 K8 @' h HRESULT GetDeviceServices(DevicePointer pDevice);, ^0 `2 d1 ~. [8 [8 U0 A" a
void StartPortMapping();
7 R4 t; K' S! n, i HRESULT MapPort(const ServicePointer& service);% ` u1 K9 r6 c5 v( |5 u4 Y
void DeleteExistingPortMappings(ServicePointer pService);
2 _/ N' ?" W0 J, {* k* H void CreatePortMappings(ServicePointer pService);
' x/ i0 q% q+ g; J HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
0 U; w4 ~6 [& c# ~( k' X7 Y HRESULT InvokeAction(ServicePointer pService, CComBSTR action, - R2 D( [. o, q5 \0 d }2 f: h4 P
LPCTSTR pszInArgString, CString& strResult); }* ~- Z" r0 L! J8 h
void StopUPnPService();2 E1 m+ v( H5 b9 j* G8 @% J
5 p# O9 a) y# s |6 H# F
5 b& H5 v3 E2 |3 A
// Utility functions
! |. O0 z A1 z* w" X HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
) e, F3 p! [4 z INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);% c, B7 W+ o5 Y& ^/ S/ f6 t/ d
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
7 ?5 @1 f( o, k4 a. ]. s void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);4 C0 e( X$ N- o# }& c2 W1 X
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
! v k4 X' \ ] f) r& k) m HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
; ^" Y3 P/ o1 F' O* s CString GetLocalRoutableIP(ServicePointer pService);
( o; e) c: Y9 N/ L/ q8 z& X8 c# k* n# S- M
8 v; ?" ^( J5 A B// Private members
4 J9 X! {# t% N3 Bprivate:( M. u3 D! N$ d' e! K
DWORD m_tLastEvent; // When the last event was received?+ a: U W8 ~" R7 J
std::vector< DevicePointer > m_pDevices; `0 e" D/ ]- U( l+ ?
std::vector< ServicePointer > m_pServices;
2 S. @1 x' M" ^/ W' v FinderPointer m_pDeviceFinder;, ]7 p- r$ F' q1 d6 Z. T# P$ L- ]- t, |
DeviceFinderCallback m_pDeviceFinderCallback;
- @ v' \! I1 u/ b4 I/ J* O- k ServiceCallback m_pServiceCallback;! m; ^5 q) _# m$ |/ |6 G, f
1 R3 h2 f, M+ N. N+ p
' ?' u- D5 \( B- n LONG m_nAsyncFindHandle;
1 A5 a- i$ l' t( i: m% r+ _ bool m_bCOM;
' O* ~) E/ L0 T( {6 m, F bool m_bPortIsFree;" L4 y0 h( \4 T
CString m_sLocalIP;1 w' S- c: _, D$ U2 R4 V
CString m_sExternalIP;2 V. i9 k# W& l7 D, z5 i/ ]2 e% }0 {
bool m_bADSL; // Is the device ADSL?
* }3 }% m+ t4 Y& r J bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
$ [/ l" R5 G8 {, E1 U bool m_bInited;
. ~2 E; B2 \( z& r' d bool m_bAsyncFindRunning;2 `$ B7 M; a) }0 J4 c
HMODULE m_hADVAPI32_DLL;9 f5 K, n6 e8 F1 i# p! F
HMODULE m_hIPHLPAPI_DLL;+ ?4 c( d, P8 @' z
bool m_bSecondTry;9 d; E7 Q1 }$ N. f2 J' l4 f- U* o* t
bool m_bServiceStartedByEmule;+ ?2 b4 W! k7 |+ _; t( s5 v! C
bool m_bDisableWANIPSetup;
# ?7 O, v3 q& `( a0 P bool m_bDisableWANPPPSetup;
( g! E( s% T1 p# Q& o n, W. B; n; C& D8 c! p7 D
% c5 ]2 G) f9 u};6 w. d, V- m! I
% L4 [3 d1 f$ z( i8 S# ?! f
# K. `3 F9 \. V1 I# \4 I% A// DeviceFinder Callback
. C8 F- g( l/ J& Oclass CDeviceFinderCallback
* a8 H1 F' D3 V# ^8 L : public IUPnPDeviceFinderCallback& r. Q! j9 b( D% G9 K; c
{* B4 k3 [, X" D5 U$ I/ a
public:0 u9 ~+ k; _5 `
CDeviceFinderCallback(CUPnPImplWinServ& instance)
) B: n+ ?# J' v5 u1 l" a : m_instance( instance )0 m/ ]- i4 g! S# V$ ` _! J: h
{ m_lRefCount = 0; }
& @# {: J" i& T# v3 |! Y7 B3 V/ _% ^0 T! `. }" d
e* h" J, h* e% H, i
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
3 C/ N- c: b, ^' y+ w/ C0 a* B STDMETHODIMP_(ULONG) AddRef();
3 x9 O3 |# S( J1 T; } STDMETHODIMP_(ULONG) Release();9 g" V/ ~# N, ~# h
4 m1 Z( }- @" z I5 W, F5 Z8 u
4 w8 O6 ], O9 h1 ^$ e% h5 g// implementation" ?# ^% R& K; v; M
private:
6 A I* s2 r3 A" a$ N, Y HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
3 D+ L' J9 n p- S2 u$ n. l HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);3 l1 i: E3 I) J$ o5 \$ z! ?5 p$ L
HRESULT __stdcall SearchComplete(LONG nFindData);
5 j8 Y) u! ~' D7 }4 F
2 F X5 `, o' G( F0 C/ [0 O" Q8 t8 P5 c& E, y. p: ]
private:
/ R1 J. z6 ~8 z, u CUPnPImplWinServ& m_instance;
* O0 g7 e1 |7 V: E( W3 V( d/ P y& V LONG m_lRefCount;) {/ m# O; e$ L7 n8 H6 ~/ M* q! ]' ^) s
};2 C" |) {: ]& i( |/ @' I7 J) |9 H
2 M' ^" j1 @# \6 V9 B! }8 {$ h6 v9 A* R% x
// Service Callback
4 A0 E3 G' x! H+ a v" fclass CServiceCallback
/ X y6 b" B/ h% a) w : public IUPnPServiceCallback0 n" H5 J$ {# P' C; A5 k% x
{; t, Q7 N m8 f+ P O
public:, w) }7 q) T1 a' W% y1 S
CServiceCallback(CUPnPImplWinServ& instance)& T4 o2 ~: w+ [4 `) m
: m_instance( instance )% R( u; }$ Z% H2 I/ |1 [
{ m_lRefCount = 0; }, U5 E8 z. @/ Q. i) B4 M
" ^3 e0 F; `* b# {7 Q STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
' f' r- P7 B0 g$ H1 V STDMETHODIMP_(ULONG) AddRef();% x/ X L6 _0 s" r6 D$ l3 d i
STDMETHODIMP_(ULONG) Release();. G0 l- k. R# t
, p# h! M4 d2 i: p# b0 o
, T& F4 r0 s3 P, `. Y3 a0 c! A// implementation" }. F" u& | x) P5 P- F. l# S
private:
+ ~; d# N1 t! n HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);! Y" }& R f' _8 k
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
7 S. J$ K" `8 i: H2 K
' o( E7 N/ N' k. Z3 Q2 Y; i
' m h3 @' J& Z {private:
$ V3 m; h0 A- R" b CUPnPImplWinServ& m_instance;+ @. O2 Z! R L* [0 k" I
LONG m_lRefCount;
) U5 G D+ ]4 z- r};0 N# ^& j3 }4 l6 U7 R9 |$ m
6 f9 l0 W% z: T0 I& d5 v0 K* e; R+ e% d! W: [
///////////////////////////////////////////////// o2 h% w3 W. @- O7 a* i
) H3 ?& f F7 B* d7 |' `
+ z' c6 w6 ^) `6 \& m使用时只需要使用抽象类的接口。& k) {( W! ~( d
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
$ t* j S1 s$ J" s2 ?9 H. vCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
7 \8 A" i6 c. vCUPnPImpl::StopAsyncFind停止设备查找.
: q# W' a2 j. n/ L' r* e% ]% `CUPnPImpl::DeletePorts删除端口映射. |
|