|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,. f! J8 _) Z8 Q
3 T5 {! ^7 j; x. z1 Y0 i
/ y& t- w& f+ J* ^///////////////////////////////////////////
* R0 K5 ]! A! w+ e9 g+ R4 r//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
" f8 P# Q0 {/ k; o! z
. R0 S0 R! W/ ?+ Y" V+ s! j
* K2 O) P# R; Z9 r' F( V$ I; l#pragma once, n9 u% _0 t, v- p" ]4 g5 ]& Z
#include <exception>
1 I$ N, r; O" z7 G6 T% b/ b) q( r* `+ T# C4 o7 e
0 T! o& g1 F6 O6 z; Y enum TRISTATE{6 L ]4 K E0 I" ^% J
TRIS_FALSE,2 I7 b6 Y$ B, \% L* K+ N3 I
TRIS_UNKNOWN,5 Z9 F3 X3 w& z3 k8 W2 |, w
TRIS_TRUE* |; l# q) f0 B, A
};5 a( A% I: u! P# m7 @" x( Z1 M
+ Q& G" u1 |; e& z' ]' O
% k" O# R, W$ F, n' P1 v; B# y ~enum UPNP_IMPLEMENTATION{
z% B6 v; s, F8 _) ]' G5 a UPNP_IMPL_WINDOWSERVICE = 0,$ Q1 m' [( a: e2 q" ^7 w X8 Q
UPNP_IMPL_MINIUPNPLIB,
4 A; h% b! m* E) [ UPNP_IMPL_NONE /*last*/
5 G. k: V/ E& W};
: l- W4 j5 K4 L1 n) a0 W
: u% _& u" Z1 C4 y/ b% y. I% E! |1 H# h7 e: P" R, k
( L! k/ E1 ^$ { A
- u) ~0 |1 n$ [! z. t8 ~/ wclass CUPnPImpl
/ i* u8 ^" U; B* W+ s: |4 }+ L# v1 B{- E1 Z* |9 w8 k+ B3 \/ F
public:# i6 Z3 u) L9 T0 z) |
CUPnPImpl();
- S0 g( _! w3 d' Y. ^' u6 E virtual ~CUPnPImpl();
+ p/ I. X3 v' x7 z$ O Q8 z' x struct UPnPError : std::exception {};
2 ^0 P6 J: ]/ X E7 J0 v; b) C enum {8 i2 r8 X; E8 D
UPNP_OK,
3 z5 ^6 h2 k, c i UPNP_FAILED,* h J% A& M/ n6 l$ _
UPNP_TIMEOUT/ |2 e% N! D/ i& h
};9 y3 [5 Y4 i4 t2 _
7 V" h3 k9 [/ K5 d9 P
! ]1 D2 u% Q' @4 x virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
* Q }7 x' c: N virtual bool CheckAndRefresh() = 0;, |- F) u& Q0 d+ K" f
virtual void StopAsyncFind() = 0;/ a9 o" K, K( q( k1 x
virtual void DeletePorts() = 0;
$ `6 V( z( h+ x" v virtual bool IsReady() = 0;& H' E! E, ]3 A6 k# `
virtual int GetImplementationID() = 0; Z6 m/ `; V3 t& |
' ]* ~! c% k( m O0 i) K8 }$ [
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
: F9 P1 o+ S1 z4 K. d# d8 j# W; B; {
/ l3 [ c: q% c' c7 G9 X) K9 l- H" g$ {0 f/ U! {- M4 n
void SetMessageOnResult(HWND hWindow, UINT nMessageID);9 D5 ^) Y) E, h9 f' }7 V3 m
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }7 ]7 x% f5 g/ Z; Q S9 h+ |2 a: l
uint16 GetUsedTCPPort() { return m_nTCPPort; }9 A5 ]2 e2 t5 M! t3 v* b
uint16 GetUsedUDPPort() { return m_nUDPPort; } ( G! j- c- G- |
- U1 z5 l. o: P: w5 ~9 [' h+ {( s M$ N ]1 c2 b4 o
// Implementation
3 E2 J: G; R# T& Q1 Gprotected:* b# P$ Q. C7 z2 r
volatile TRISTATE m_bUPnPPortsForwarded;
$ y! i) C' u9 u; T void SendResultMessage();- n1 P8 E: c0 ]) {
uint16 m_nUDPPort;$ m4 o3 J+ H, I" [# @* n( F
uint16 m_nTCPPort;
9 x5 {. H/ q! N, T uint16 m_nTCPWebPort;
3 y+ ~" ^- _. V& R. z; H bool m_bCheckAndRefresh;! V) G4 A' ], J- n+ M: ^% u
: Q: I" d" p H+ H7 I, U5 W0 u' m6 D; `% p0 e# W; @8 N) d# S" O' j1 J
private:
0 i* R0 m/ y6 j; { HWND m_hResultMessageWindow;
( [9 l4 @8 v) v2 a. u UINT m_nResultMessageID;1 ~6 n9 A% h* f# d! f; N n
+ Q6 [1 _9 Z$ ^/ s
6 m5 f) v7 S' Y; }! ]5 Z8 x};. y; q: L9 N/ o
. Z; [+ G5 H& C* s, g, T" d& C
& H' q; ?4 c _# k" I// Dummy Implementation to be used when no other implementation is available
* z8 e8 a3 O/ @# j" L4 eclass CUPnPImplNone: public CUPnPImpl
% S) h$ V/ X3 r{/ i4 u" o) ~8 A' l+ }0 N+ F0 c
public:
( C6 C" v* R/ F9 G. v( w5 v) w6 Q virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }+ D/ E$ o3 Z, K$ K' s# O
virtual bool CheckAndRefresh() { return false; }. e$ g, h ?6 m8 X7 ~' F
virtual void StopAsyncFind() { }
% i3 W$ \) o7 B3 R) Z virtual void DeletePorts() { }/ P( `% ^; x: E& {
virtual bool IsReady() { return false; }
. ^5 ?. { m G virtual int GetImplementationID() { return UPNP_IMPL_NONE; }, ~/ }) j( }" V: I
};; l8 M0 B W+ O
0 {% \8 ?& w* V2 f
' Q- p0 g; I/ \2 s1 f- q/////////////////////////////////////
3 g, Q& Y1 x* C' J3 x1 `; F5 n. M//下面是使用windows操作系统自带的UPNP功能的子类" a7 Z2 a$ U0 Z! G" o5 v
. T" Y1 f" Z" W" |# y; o- f5 j0 G9 \" P0 ^9 x5 ~- L4 N: M# R
#pragma once
" G. z" F9 H1 [$ _, e#pragma warning( disable: 4355 )
' S) W, |( p0 B; N3 l" r+ W
! [8 V: q2 @# l* I6 }, n
, v; x: W' p* f" a, A7 d+ m#include "UPnPImpl.h"( J" m8 D/ i$ C) c* M) [6 R
#include <upnp.h>
8 X& A- l) U/ @( m5 v" h1 b+ t! V- r#include <iphlpapi.h>
7 }. @. L+ S: l/ [8 w#include <comdef.h>
- n3 M2 j# L- a& D9 M* ?#include <winsvc.h>5 C5 I7 C# O9 T4 `* U E$ @
! {) ?: G% W/ m, Q& q, t
% u6 C# c" x' J6 q+ F
#include <vector>& U6 B8 a" k7 Q/ I. B! v
#include <exception>
% t2 n# {8 \) W; U5 _1 ~#include <functional>" ?5 a* ^3 V: u$ W( N+ W4 j5 g# z
8 G' z5 B8 U% q! R o
) l& q/ B& f+ w
% C7 r* ], m" h
9 p' P! `: s# p4 r- L4 F# a; e1 \# etypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
6 u y0 Y5 C; Q: y0 b8 qtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
7 ^: n, C- l; ^4 W. @% D; `9 Utypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;$ D* y( l1 I( O" K. h7 C
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;# O) ]3 C. }8 l( T: [
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
) M; k6 G9 q7 s* s" Y' Otypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;* H3 B1 a. `4 v
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;* e7 q( G- l' h$ W3 r( K. r6 @
! F& I0 s' s$ o1 w# R
- _: W: G* q- g9 Xtypedef DWORD (WINAPI* TGetBestInterface) (, s5 o& i2 n: V
IPAddr dwDestAddr,* _" q5 [8 W: i* ?9 ^ C
PDWORD pdwBestIfIndex
1 T- s# n: m2 s. L' ]+ K$ k);
: ]# k1 o! [, o* H
4 `" z- |, N9 }; _- L& k% v' S% V- L
typedef DWORD (WINAPI* TGetIpAddrTable) (
! n8 O( R+ ^# H$ Y0 s! ~( B' w: R: o PMIB_IPADDRTABLE pIpAddrTable,
1 }. j9 T9 k) q- W8 Q0 ] PULONG pdwSize,
' _) ~0 M! w/ a$ D! S2 Y BOOL bOrder6 K4 C) T/ K+ |1 o
);
/ ~* A. t3 ^. m7 k1 G; ^" ^
1 B# x: S8 I/ J. p' [: V9 T- K# b$ `6 X
typedef DWORD (WINAPI* TGetIfEntry) (
, R9 h& n( g6 }% _% x ?$ R PMIB_IFROW pIfRow# x9 A: t! Z* K: D, Y s4 E: i
);' ]) T' C. y2 L8 L+ A
8 J( {! Y5 D, g! j5 n
1 E/ n" C3 ]) d+ u2 t2 o; a DCString translateUPnPResult(HRESULT hr);
6 e& I0 p6 v3 k9 x$ Z. yHRESULT UPnPMessage(HRESULT hr);4 Z% f. m1 O9 M! @/ j+ O
W$ F- ?7 j% E7 @0 V/ ], `
6 q$ \" ?: C2 F- a! p& `) Iclass CUPnPImplWinServ: public CUPnPImpl/ ?; [) i& q$ S! `% _
{
8 Q% s" s; W t3 O. w% U( p" M3 q friend class CDeviceFinderCallback;" i# G7 [" _! Q- c/ O2 _+ I# X
friend class CServiceCallback;$ k) G( ?& x. L* A4 i
// Construction
" o. k$ v2 L$ O" {; A2 epublic:
( a. H% V) F% x) J/ t3 Y; |! @3 v virtual ~CUPnPImplWinServ();9 H+ v6 l$ U9 w. ^7 E
CUPnPImplWinServ(); n+ r. Z/ i* c* u
! M9 y1 Q; I5 U1 m6 `" m) ?
. H9 q0 S7 @- j% A virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
& i( U7 C& G: u9 \! `& Q& D' L virtual void StopAsyncFind();
: R9 \1 D- b+ g z6 M2 k- Q virtual void DeletePorts(); j* r. ^+ `/ B; K8 R4 e" E
virtual bool IsReady();7 x* e: u3 e2 P) D5 q7 M/ _
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
- o9 ^1 {1 N. R" T/ m
6 P4 C2 }, U3 \/ N; C) ~
8 R+ {' }$ G$ a/ k; R% u // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)6 D0 K* H; f* }7 \+ b( Y8 w% G
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
C% W. u1 {7 x' b/ H8 u0 [) ` virtual bool CheckAndRefresh() { return false; };7 \/ F2 M6 m- l$ I# R+ j
6 m4 b4 c2 w/ M8 o4 B& V, g6 l& v3 X8 Z
, N8 n% s |; |& w- Nprotected:% t" v: ?' Z4 z' [- Q# q0 X% q4 ^
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);6 U9 q; k9 F2 O1 w$ Y5 P( a8 V. b
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
q) M0 h; _ I* s void RemoveDevice(CComBSTR bsUDN);
2 y/ l% @' }# t% ^- ~ bool OnSearchComplete();
! d* X5 i/ j& M+ K2 ^+ b void Init();8 z! L, ~7 p; \- R
0 |# |. e1 b" E# ]: h7 t
; X! m8 f) o+ F3 i9 a2 R inline bool IsAsyncFindRunning() # G* X9 @5 g* x: c* \
{
! h" {3 _" D5 E# S4 U. S* F1 i if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
# r2 ~. B# ]3 G1 ?2 A- p$ _2 a {
' ]4 `# b3 T4 q0 `% ~: F4 @6 o& I8 N m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
/ p( x% f; x" H; F& N/ _9 g: Q m_bAsyncFindRunning = false;
5 \+ V; p% ?& F2 s' J" M$ ]8 a3 X }7 k' M3 s3 D- T. s8 Z6 j- y
MSG msg;3 L$ `4 R: w/ f8 F
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ), F2 M9 \/ j% O: Y
{
& \' F/ b- H/ c' D TranslateMessage( &msg );/ L* M6 B' r7 D" E
DispatchMessage( &msg ); U, p" D% K1 j4 P/ ?, g
}; s2 p1 d! n; {( r% Q) M2 H3 @
return m_bAsyncFindRunning;3 F9 n9 L" `9 K6 c
}
: \! E! u; |2 y
`) f0 U" J2 s# r& t" D4 m. F5 X
& r! i2 n9 B( b c TRISTATE m_bUPnPDeviceConnected;. ~* N: s' E4 n! M# V2 [$ J0 c7 O
; T* V' p& F9 }4 I: l' _
E* r+ b# a# p0 _// Implementation
2 q' u5 T, H5 D // API functions% _1 b/ Y9 Y( d2 P
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
/ R8 j: J' i2 L5 T1 i& _: k SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);! I6 z' v- k7 T; e) w( F7 l
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);7 r: f- k# F* g, b! G& q
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);% b- n8 F9 O Q" M, {* K
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
5 d' R- x- [' o+ t# B BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);7 u4 S3 a- ]( F8 ?* n6 _/ q
' Q3 d9 B1 X; L$ S: A" {) x
( t0 s) _$ G* }! P" F
TGetBestInterface m_pfGetBestInterface;( V& ~9 O8 P9 q1 H1 m
TGetIpAddrTable m_pfGetIpAddrTable;
7 c" u' m( X: S2 [, n) t TGetIfEntry m_pfGetIfEntry;7 L8 g* E3 F7 ~) f: S( b
! Y1 {; |* O1 m
) k1 z8 O" m4 e" B( c/ y& [& O
static FinderPointer CreateFinderInstance();+ ~- }! Z7 Z7 w# {( T
struct FindDevice : std::unary_function< DevicePointer, bool >0 A6 ] l- A3 d! I8 ^, @
{
0 G( Q$ t& ^3 J- V( a/ _$ ]! b FindDevice(const CComBSTR& udn) : m_udn( udn ) {}7 W$ m3 l h( T/ e& V' V8 m1 v- N6 e
result_type operator()(argument_type device) const
% @- j& E6 p% W W Y4 g {
/ e/ |, v3 T0 _/ {# w) w" ` CComBSTR deviceName;2 ?5 H% @3 K0 T; a
HRESULT hr = device->get_UniqueDeviceName( &deviceName );; [. N. Y4 b1 {
" n. h# t4 H6 y& s, G# f
* }6 Y1 D$ {) r( |9 \3 |( r0 ]& H; M; ] if ( FAILED( hr ) )
# d; m; U; A. [2 O return UPnPMessage( hr ), false; ~3 |- O- W( w' K
& R$ N. s6 p% e8 U
4 B4 |% q4 \( u I0 v return wcscmp( deviceName.m_str, m_udn ) == 0;
, @4 G5 ^, H7 D! w) w) R }2 P- X( B* r7 N
CComBSTR m_udn;
! G3 M, p1 A4 J; ]! J! w8 o, g, m };
9 O6 |! J8 y, z& z# C" B* A- b % e- e$ g3 y( z' p. Q7 a5 ?
void ProcessAsyncFind(CComBSTR bsSearchType);
8 f' E+ n2 O+ P C8 s) w HRESULT GetDeviceServices(DevicePointer pDevice);- {5 v! c( e* a" P9 L5 g
void StartPortMapping();' ~1 j4 H+ G9 @% Y3 B5 f2 s
HRESULT MapPort(const ServicePointer& service);9 c, N* h) a8 v9 A
void DeleteExistingPortMappings(ServicePointer pService);
' B/ \/ [; c# Q( A void CreatePortMappings(ServicePointer pService);! e! x' G! G9 w# j# Z" ~. z
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
/ Y+ S6 ]# V. C9 }2 m5 D& M HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
7 G4 u) G! P4 B4 c b: z0 l LPCTSTR pszInArgString, CString& strResult);8 r4 J8 Q( ?1 ^/ ~: L3 y3 B0 j1 _
void StopUPnPService();# {! m% Z! C- [" W. d: \
# p* N- M9 w' t- p& C4 |
$ X0 }( X/ }0 m$ d7 g$ @' N // Utility functions4 i% E% z/ i! r, m5 Q! Q
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);) i! }3 R- B: |' C
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
1 U3 A( J( g' s2 ~% }" u/ \5 E INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
; |5 a0 s9 @* Q- S void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);4 T1 H' i- H/ Y3 V$ K2 Q+ f
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
& i1 u: ]1 Q7 z: ?1 A& s4 x* D+ [/ k$ Y HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);. P; _; q0 \1 k# @$ g/ {
CString GetLocalRoutableIP(ServicePointer pService);
' x8 |7 j2 g7 a4 b/ a n S8 K+ V9 Z# V0 i( N
* U; u8 P" U# @) B/ Y8 W- m
// Private members
+ N0 b9 W0 b% P' }2 v8 lprivate:+ ~8 }# _# C5 d! U! E
DWORD m_tLastEvent; // When the last event was received?/ h: q2 H6 ]& K- ?8 U
std::vector< DevicePointer > m_pDevices;
7 k8 v- Q- T# \) _2 K, I+ W std::vector< ServicePointer > m_pServices;
% b% `, x6 u: g8 [ FinderPointer m_pDeviceFinder;7 L1 H- ^1 U; S' z
DeviceFinderCallback m_pDeviceFinderCallback;
* L9 V) X [; j' S ServiceCallback m_pServiceCallback;; E% S$ _- o0 }! E. o
0 v" [! G1 g) k, Y) t; B0 Y9 y0 @8 k& Q2 |4 H& f6 _7 j
LONG m_nAsyncFindHandle;' g3 F5 U. Z" P* `7 |
bool m_bCOM;
6 w+ w) i5 [5 |5 M: t7 E$ @ bool m_bPortIsFree;
) n6 f5 W) y; G0 W* g* a. W CString m_sLocalIP;0 W4 A6 i7 J! M3 t7 p. _
CString m_sExternalIP;
& t. R6 {# c$ X+ a bool m_bADSL; // Is the device ADSL?
. H% j& m4 h+ h0 F* N bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
m. q) x( m9 v' \2 d bool m_bInited;/ `0 i" p, U# B* I! ^; ~ X
bool m_bAsyncFindRunning;
% b7 H8 ]. f+ T' e: D HMODULE m_hADVAPI32_DLL;% L. |; i5 e4 Y( i/ p
HMODULE m_hIPHLPAPI_DLL;9 L+ n4 i( u7 Y m; E
bool m_bSecondTry;
3 \( Y9 d4 Q7 e+ M% R bool m_bServiceStartedByEmule;
( k" z* a1 {0 P( ? bool m_bDisableWANIPSetup;
u" s Z4 F. |5 R5 g t bool m_bDisableWANPPPSetup;
' y; z+ Z! [# O4 M9 C9 N0 e X3 j/ {* @; j/ r
- }( c# P M/ w( X6 b
};
1 ^/ {. u, z% X+ e ~) O" e( u0 ]* y3 q H \7 [
5 m. ~# v& p2 F5 J4 G: J! E1 I% k% ~! f
// DeviceFinder Callback
9 ~0 A3 N, R- [. ~. P" ?( Aclass CDeviceFinderCallback
6 N5 [: y& Q3 @% i5 _- ~9 i. g : public IUPnPDeviceFinderCallback! R5 f+ q3 w! b7 o. v- {
{
8 N5 L' j8 \% j0 f( Rpublic:5 n* @3 j E, S" m0 S' @! X
CDeviceFinderCallback(CUPnPImplWinServ& instance)& k" Q8 X9 x; \7 l6 ^5 z% p
: m_instance( instance )( l2 [6 A3 r3 b! F8 S( G; \8 e9 c2 Y2 s
{ m_lRefCount = 0; }" Y) }8 p) X4 x
9 H: a8 \/ c& X, A
2 g5 m4 g0 S: S& A% D STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);& P5 S a, Z7 P; I- }$ X; s% x
STDMETHODIMP_(ULONG) AddRef();
2 ~$ @" U: b$ Q9 Q STDMETHODIMP_(ULONG) Release();3 C A3 |3 f Q N5 M$ B) o/ E
, m& a" v- t9 @: c/ b
1 N1 e2 @: Y5 C0 g I' x% j9 C// implementation9 Y; {, M4 g: Y- L, R$ D
private:
( A( X ~9 m$ A0 w HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);9 y6 [, I) M" ^9 k
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
8 _0 r$ f8 K; Q- { HRESULT __stdcall SearchComplete(LONG nFindData);
& C9 z' C5 |8 e/ Q( W/ _; _/ m/ s% r+ `* o) D: d) n ^
. M) O% o0 y* j* g. q5 Lprivate:
8 j: C- s7 U. t) S( ? | CUPnPImplWinServ& m_instance;
9 e5 t0 |- v2 }# }( J1 w3 a4 E) E LONG m_lRefCount;
9 \4 d/ A& B7 {' q; W0 [};
Q+ c5 p- M4 m/ X9 P+ Y$ c/ M
( C. H z' X4 ?( Q. z
" F; {6 o6 b0 V+ o2 }' h& u// Service Callback
3 m, e) i! j# q/ Sclass CServiceCallback2 {) D$ Y7 k2 g+ B. K
: public IUPnPServiceCallback o0 o' t7 \! F5 I4 X- ~( |
{
n& l, M: K) e' K2 Ipublic:& I) n$ Q* G" R7 @
CServiceCallback(CUPnPImplWinServ& instance)' ]2 ^! P; E1 m; e" l
: m_instance( instance )
+ [) ]9 r e: r) Q5 i: M- |3 ` { m_lRefCount = 0; }
$ E3 }) }! c6 k; I" c; j 1 T4 ?, G6 j1 o
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);0 W, l! u: D- j4 g
STDMETHODIMP_(ULONG) AddRef();7 f8 I& ^ `# J6 B- L. r8 t! K5 o
STDMETHODIMP_(ULONG) Release();# q, f2 J& I* T! ]
: A- {# Y4 V$ j6 h1 K7 c8 y4 u
1 ]. e" ^9 W8 x S8 O g7 Y
// implementation
' p. i2 L$ M8 d$ o% h" b- mprivate:
& N: f: z9 Y+ N/ C HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
- D; f7 M n/ O& z1 E HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
. D! _$ u3 j' l7 }# M1 ^1 T( f- i
. t4 T' v# b) W6 U3 z- X
private:' ?# [3 E. f: Y+ c
CUPnPImplWinServ& m_instance;* K$ j4 [4 [$ V! X# ~
LONG m_lRefCount;1 \( f& U- c, V3 N2 h: ]2 }3 @( K
};9 B, d2 O0 H/ ~
2 V- q5 Y3 R: M5 q& Z
% ^' S! n" K! k
/////////////////////////////////////////////////
/ I& c; J" {% o; x- A
% }1 D4 u1 A) A) E- O" p4 W$ o7 `0 J3 P9 ~7 {: L4 Z' @* j! x
使用时只需要使用抽象类的接口。
' E, o; K2 @% M2 v) pCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID. M& J7 ~/ F I2 ], _# ?
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
+ Q& C; y$ K7 }. l' I% nCUPnPImpl::StopAsyncFind停止设备查找.
' _9 d5 C+ Y9 g6 X0 U* B7 U4 O# E, yCUPnPImpl::DeletePorts删除端口映射. |
|