|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,- G- _1 N2 I: i8 i. d: \
* h+ k, p9 d' l$ s4 [4 k1 g. g8 `+ a
///////////////////////////////////////////
& C5 `: M ~/ V! ]' L/ v4 P//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.: I- F8 {5 t3 I8 ?! |6 y8 A
% m. V" Z' t: _& {9 r( ~% @5 m z. `
#pragma once. l% a! V W+ R
#include <exception>
/ f$ k) y0 v+ X
{5 z4 f2 ~9 s8 g7 ^6 s1 U6 g7 [
& U% P8 w; k3 C6 s3 b' N enum TRISTATE{
! q1 r2 _% }6 |# m7 {* O9 \% f& C TRIS_FALSE,1 L& B- w7 q! W) N2 o5 h* t6 M4 S/ a
TRIS_UNKNOWN,# I3 Q6 Z" Q1 H' d: F2 B5 z! q
TRIS_TRUE
F$ i4 k0 t# l6 ` {; g' D};; O: T5 N, P) u8 l
7 y# n5 X" T- j1 ?9 G
' r, V( K7 x+ j+ ^1 T$ b
enum UPNP_IMPLEMENTATION{
" D/ ~& g, T6 L* [- ]: d/ X0 S UPNP_IMPL_WINDOWSERVICE = 0,' W, A+ `: M+ C7 `
UPNP_IMPL_MINIUPNPLIB,* d+ @% L" _9 w/ x2 Y7 i6 `
UPNP_IMPL_NONE /*last*/4 K1 f; Q; Z8 M& j$ q; P2 q
};& \) c7 t: d1 W6 r+ T% g% F
% T H1 e W1 t
: g3 Z" B+ D& t
- t( K8 }( r' ?1 q. V) i% j! m- r) o/ l! r) U9 g) @# _
class CUPnPImpl
, S$ \! D, v2 n7 O- q- x% F{
. R" j5 {; D: B) gpublic:
0 r( j7 k* e! c& i6 E+ ~ CUPnPImpl(); v e9 _/ D' ]7 s6 t8 u5 e- b3 s
virtual ~CUPnPImpl();$ y. Y3 A/ E z3 v7 K$ F2 `
struct UPnPError : std::exception {}; N9 G( ^$ j2 A8 o& a% V! Y8 e
enum {
) w$ j" v; }) _3 n. N: K! R. y UPNP_OK,
: ^: a' m5 ~/ M; L- Y5 O UPNP_FAILED,
: o6 Q, }! t2 Q, w0 i6 j" M UPNP_TIMEOUT
6 a; I: o. i1 k5 `) }' ? };
1 r; h' a- |! v; Q. \. V& t1 r3 B: t
6 Y: v% |8 s% w g, L1 M# E0 y5 d* }6 }, v7 @% R: f, f3 y* o8 U; U/ S2 ^
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
+ X2 ~5 S4 m6 }" ? virtual bool CheckAndRefresh() = 0;
6 P4 G8 S* T8 w% f virtual void StopAsyncFind() = 0;
$ ~& V1 ^- e- B* k! M# U virtual void DeletePorts() = 0;2 J, d C7 d7 ~# a$ @
virtual bool IsReady() = 0;$ t( I, N8 l' O+ R; d1 `& z
virtual int GetImplementationID() = 0;2 _5 g4 s% g- w- z6 Y0 n( e) y
) z" M- Q' }: A/ k# \: g
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping: i) q8 E/ |1 `8 g' g' j! Q+ R+ l
6 X6 |, f- g" {3 t1 V; m
& m4 `* a/ Z i
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
+ v# ?8 j% C# _" N3 `1 W TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
$ r0 L/ Z1 P& F uint16 GetUsedTCPPort() { return m_nTCPPort; }9 a5 \9 l; r. K# \5 Y$ _1 B, b4 c. @
uint16 GetUsedUDPPort() { return m_nUDPPort; } 7 D( ? F6 U8 u8 D+ {4 \1 A" f
% H/ b6 F' C1 T+ J0 {" e
8 ^+ i" L- Q$ ?
// Implementation
. ?: T7 e! Z5 o0 c$ T0 C3 Hprotected: |1 u$ p0 \$ N" {0 R. h! F
volatile TRISTATE m_bUPnPPortsForwarded;
1 w/ E; U: O1 b1 p3 x4 M void SendResultMessage();7 M% v2 o! \6 ]/ @' @- z- |7 V0 Z
uint16 m_nUDPPort;
- U" p1 S0 I3 O0 o/ a* k. Q1 [ uint16 m_nTCPPort;
/ n; i5 A% N4 z& B uint16 m_nTCPWebPort;
: ]& O/ _% M; i# k1 u2 n2 W bool m_bCheckAndRefresh;" t/ }4 _2 E# |+ v, P2 V e: z4 j$ v
! \- {1 Q* u" x5 T7 m% X5 w3 r1 i# X; O) P9 r/ H# C4 o7 ~7 {
private:2 o+ W5 w! r# i
HWND m_hResultMessageWindow;( w8 h6 l: Y5 p3 f/ Y) p3 P
UINT m_nResultMessageID;8 t" b) c7 M3 T7 O% g' t. \
& X$ M# h7 p/ b- K1 K l1 i$ |" E' H
9 ]( k6 O5 o, i' Y};0 n; d9 R6 c2 I4 D
7 D; Y* W- R. l9 r% W: E
( |; f# o( g6 H- e$ z' N W// Dummy Implementation to be used when no other implementation is available
5 \/ M& C0 K* z* _ k {class CUPnPImplNone: public CUPnPImpl
9 J; y% A3 u/ s: p{
( f/ g+ O& t4 |) ]1 npublic:' d! y; t/ s9 `7 x0 y" T) V
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }# j( O: X) F+ } v2 N. \
virtual bool CheckAndRefresh() { return false; }
0 W( v7 ^ N0 @6 G virtual void StopAsyncFind() { }
! L! P0 i5 ?& C7 h* b# s i# e virtual void DeletePorts() { }; G* G" M: d- B" M$ p) i& R
virtual bool IsReady() { return false; }! C. }1 \0 X2 L4 f* w% U* E
virtual int GetImplementationID() { return UPNP_IMPL_NONE; } i+ b8 ?1 y6 A
};, M9 x; B* v, [0 q
: o* g) ^, I$ q2 \, i1 R
$ s4 H& _4 A# I4 r, e5 l/////////////////////////////////////
" ^$ @1 g$ H8 O6 A+ I' @! x//下面是使用windows操作系统自带的UPNP功能的子类
& U# Z! Q- Q l% b6 [# u: _. r: }! s3 X1 L
/ S* o/ n/ `, W#pragma once/ o& S2 t7 C$ Y) p+ K4 j
#pragma warning( disable: 4355 )* n3 I: f% l4 F3 R& E. [
3 g0 |- N& G9 R6 G. {; w( F0 {. h. n' `- \" I! m
#include "UPnPImpl.h"
" q& X T3 M! K- z! w) T+ y#include <upnp.h>5 B& e$ `1 B i" B4 L
#include <iphlpapi.h>6 k" M3 N7 q: e. R
#include <comdef.h>: T! r- r- V2 ~( x
#include <winsvc.h>% N0 X3 Y: W6 W' K; O1 H
1 c' y2 ?1 |/ t; F
: @6 ^' @, I* V7 z/ W: z9 D
#include <vector>% G: |$ t& e+ h2 s0 k4 u
#include <exception>% j1 ^! f3 x- l, _
#include <functional>8 g8 o2 i M* |( M# {1 u
I, d! B8 ? D* d8 t
! |; H" @9 |8 t+ {& ]
$ n* t( E( P6 a3 t5 U$ u) z- J) O9 S9 X5 r! T1 v# a
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;- l( m7 r) T' R. m1 `5 {
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;6 V# l+ d9 k% D) y% G7 U' J
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
: C' ~! c0 N, Wtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
( T7 v! M$ {7 Z/ Y# ~7 X: ctypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;" o' M8 I! _) n! m9 K/ ]5 S. t
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;( I& O# i9 @( S6 h
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;0 K; {( }2 Q2 b5 j; G# t
* |2 T' q" o6 g7 t8 K
7 j/ @( d* M$ s4 h% z- f" m
typedef DWORD (WINAPI* TGetBestInterface) (
3 k2 \$ X5 v( i9 r3 \8 c IPAddr dwDestAddr,
% g( N3 c! |! U2 M2 G* r& f8 b w PDWORD pdwBestIfIndex1 A+ `: j; M8 ^" W! \
);
9 e: ?: F( { ~( Q$ ~
' x5 I" o5 H* U+ k! h
" U. m8 J* S1 _% X: n9 xtypedef DWORD (WINAPI* TGetIpAddrTable) (
2 `8 J* Q) @0 j+ O1 l PMIB_IPADDRTABLE pIpAddrTable,
9 s1 W. m# j$ Z7 h+ I PULONG pdwSize,
* n5 t$ h" X% _ BOOL bOrder
: J0 l9 W% H& {5 _( |7 w" g4 P);
! L- q# w: I i) b
& t. T4 F; X. S3 i+ X
; [" |! N( m$ F% R! [0 V: {; E! dtypedef DWORD (WINAPI* TGetIfEntry) (- _( s' @' x2 b+ P) s; l# h( I
PMIB_IFROW pIfRow
/ x4 L" p* u" b6 v+ E7 @! b);
1 ?- y/ x H2 O8 s5 ~* D2 g; ~) r% k0 M, h# |& g9 t# |
" F( v7 l, p2 K
CString translateUPnPResult(HRESULT hr);0 ^1 a* d! D6 M: Z- d" v6 Z
HRESULT UPnPMessage(HRESULT hr);+ n2 B4 D! h4 A2 A) p) Q
' x$ x" y1 X2 I6 c9 J; A
- p/ b9 T! ~, G! q ^# g: X
class CUPnPImplWinServ: public CUPnPImpl
+ f" s* e7 l5 @5 j{
( B. x5 o1 W V$ i0 h& y. ^ friend class CDeviceFinderCallback;( }# h6 y' g$ l/ C
friend class CServiceCallback;
2 F* [$ @6 p6 C. c/ M' q// Construction! S" p' l. c+ _' e* o! z4 U
public:6 b3 T- k" \' {2 A* h- _
virtual ~CUPnPImplWinServ();: _* [. |- ?6 F: \. m
CUPnPImplWinServ();
: {; v' J& L+ ~0 V$ D0 \
% E9 d: U3 Z- P" G! l% x( F% {, t, h' ]" h, O
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
5 r# y2 O7 u- O0 D virtual void StopAsyncFind();: G4 A9 Q: K2 C8 D6 \5 g
virtual void DeletePorts();1 O0 ?( Z: w% s9 P+ U
virtual bool IsReady();
; d0 \& l+ [, W virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
- f) a. F: a# Q3 a- d$ h; k
" f; | M% h2 u7 y' c6 R. S
9 \3 ~6 i; P, r( n, P // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
" i" U' p+ J1 S3 G7 `+ {" e! `0 J // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later- ^! E) @! A$ N1 `7 h4 A% Z$ {
virtual bool CheckAndRefresh() { return false; };
3 x" j# E8 Y! f
$ P! K8 N2 n/ M% p2 \! u/ M
/ \) k: a v* n S- N6 {9 o* Bprotected:
6 f: K% a! V2 c6 `0 D7 k void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
- c# X, r; u/ W* l. q% S8 C0 G void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
8 ^& p% q2 C+ j/ t- n. [) ?3 M void RemoveDevice(CComBSTR bsUDN);5 P2 d, Y% A! U$ Z
bool OnSearchComplete();7 `2 `$ h& e" m3 z- Z
void Init();0 X1 C: c- V" |& x9 Q
- V- C$ V6 Y# W4 G; E% }4 J
8 Z, k# U9 B9 r$ [. z% t( T7 ^0 |
inline bool IsAsyncFindRunning()
; Z, Y' {/ v: a+ B1 W6 f6 W# m6 v {9 q5 N/ O( J+ J/ j
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )* f; X8 O$ Y* H% A) u- y/ D) n# E% ?/ c
{& d% f! t5 r a4 r: `7 u
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
. u" \' Y3 y. u6 d m_bAsyncFindRunning = false;
" M8 O" C( }4 Q+ v }
' j# l9 p; i2 g MSG msg;
- `& ]4 f5 D! ?0 \6 G6 H8 \! b2 D while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
6 L& B+ B: ~ g {
& C# M. @' d7 J* ]( A% b5 U TranslateMessage( &msg );, b' \$ b; [ q3 S5 H
DispatchMessage( &msg );* y6 c# x$ S. z# H
}
- a- ^, X1 P; E1 H) ^: _* r2 S return m_bAsyncFindRunning;. P+ ?, |- x n
}
+ J, ~0 [0 a/ w: O4 M ?2 S# e! s% w f }5 O( G8 [2 U
0 Z3 T* u6 r2 r5 m' G6 X2 [0 g TRISTATE m_bUPnPDeviceConnected;
0 `. N Z8 O# U. j8 {$ x9 ?; G! r
6 M2 u4 Z* e( z$ c$ C y; R$ a& a4 e* c& d" j! k& h# B
// Implementation
1 ?* o$ k* L3 v5 e& P // API functions
: I4 M! V; N7 u1 Y4 g+ E' A SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
: y$ _+ L/ s+ r2 q+ a1 } SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
2 C1 D' b; {- \' L BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);# h k; w$ ^! U4 b9 B+ Q
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);, g1 t9 u0 j, t3 L
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);8 j& G6 W7 {; z/ [1 |' ~* E
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);- j% B c5 u9 x* J8 M
* e) s2 C- X! g. g1 z3 c( ^
0 f5 k& C( I+ `/ B+ j2 l
TGetBestInterface m_pfGetBestInterface;: z! h' V3 v. B! r
TGetIpAddrTable m_pfGetIpAddrTable;# C x! K+ O3 @2 x+ E; d# o
TGetIfEntry m_pfGetIfEntry;$ w: l( Z5 c2 j5 {
+ W7 c+ }1 V6 x- y) M2 Y9 `7 c4 l
static FinderPointer CreateFinderInstance();$ ]7 y7 l* f0 I) a! I7 ~" V
struct FindDevice : std::unary_function< DevicePointer, bool >9 X( Z- T/ o& z/ o
{
2 n7 Q5 P( d. ?6 P0 s; ` FindDevice(const CComBSTR& udn) : m_udn( udn ) {}& k5 L2 u) `/ L! ^
result_type operator()(argument_type device) const
% o- Q+ X* o! ]+ U0 J% |7 f5 ~& M {3 R- K# g3 W4 v6 ]7 I. T
CComBSTR deviceName;8 {* h6 _: j; [7 f9 U4 ~$ j
HRESULT hr = device->get_UniqueDeviceName( &deviceName );. q1 L+ W8 S1 h" D
# t, u) |3 P @& b" e6 \
' [) m) A* f, z5 C if ( FAILED( hr ) ): J5 a6 \6 I7 u. H
return UPnPMessage( hr ), false;* {9 P0 f* R( s
' n: W$ ?3 o6 l# {- G; J
' g- r: E; k; Z0 P
return wcscmp( deviceName.m_str, m_udn ) == 0;" n4 U, j0 G3 S" J, q/ y
}5 O) ~# m& c K7 t2 U) C
CComBSTR m_udn;
8 k& ?5 e- h+ q* [) n5 a };- }0 L" K' i I6 `& q
3 t) W8 n" J: r+ S, ?) H void ProcessAsyncFind(CComBSTR bsSearchType);2 X- b" A, L7 i* v
HRESULT GetDeviceServices(DevicePointer pDevice);
/ S3 D8 X. g4 ?+ ^" x void StartPortMapping();
5 p4 @* k, C' ?3 E5 T: ` HRESULT MapPort(const ServicePointer& service);
/ W( y: Y& B, x, {" g) p3 E: r void DeleteExistingPortMappings(ServicePointer pService);
: @2 R# S) c$ l0 K% l, F void CreatePortMappings(ServicePointer pService);$ T4 A# M! O# g& J
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
! ]* _" w9 v3 C3 I7 V6 m) B HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
& d, i: n: x+ J7 } LPCTSTR pszInArgString, CString& strResult);9 q# [; a) U2 t- }
void StopUPnPService();
5 y+ {* c1 h! F9 e" \
* E( ~+ F/ O$ R
1 z8 Y; w H$ b. A // Utility functions+ p+ D q% `3 P4 H/ {3 C2 n
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
: @0 m0 n% j; G( N N% a4 } INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);& `" k: t8 a" v: ^. l5 f
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);" M- x0 M. N) z
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
: [- j+ E: R8 J4 B" R, r$ z" p q' G HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
2 E( m2 p# W5 j& t0 L* V. N. F5 C HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);, c5 p: ^1 \; Y: W8 g
CString GetLocalRoutableIP(ServicePointer pService);
* w/ O: u' \& @
( M" `5 Z, F4 }& j. C8 N# u5 H: S: i/ m6 M( G' U3 p
// Private members9 K& k" ?+ _0 u$ a# f8 P1 K
private:
( j- T6 B# w K+ Z; v1 c DWORD m_tLastEvent; // When the last event was received?
5 O+ i) Y6 T5 R std::vector< DevicePointer > m_pDevices;
8 T% ~/ Z/ S9 @$ X7 U& j std::vector< ServicePointer > m_pServices;
& W& L% I% S+ E2 |. C% K4 ~ FinderPointer m_pDeviceFinder;3 a/ P9 ?! B# ]/ p( z ^$ ?
DeviceFinderCallback m_pDeviceFinderCallback;7 t" G& [6 x: V4 U( G# C7 r
ServiceCallback m_pServiceCallback;& T' z* D. ^# F) s& n) n% N
" L4 ^8 N5 Z. s$ B
6 u" c$ I h% L3 z LONG m_nAsyncFindHandle;
: t. m1 g; y7 ~8 V2 p+ [5 b bool m_bCOM;) e U5 `) ?0 p5 i! U, V7 {4 D" l
bool m_bPortIsFree;1 q& p5 x$ Q- y
CString m_sLocalIP;" _% d, `6 ], y; l
CString m_sExternalIP;1 `1 `9 b0 b: |8 O
bool m_bADSL; // Is the device ADSL?( D1 W5 |) _, \* b( x. ^. t
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?4 {1 Y0 s) o; ~" K8 @6 a7 i
bool m_bInited;
% ?) |: f9 {3 `5 E- }" ]; T0 m bool m_bAsyncFindRunning;! m" w3 g: f1 x* h0 o
HMODULE m_hADVAPI32_DLL;0 Y4 N% r9 c$ \& x/ b. e. D
HMODULE m_hIPHLPAPI_DLL;4 @7 T2 M7 I0 C6 b" a
bool m_bSecondTry;
' {) F* Q8 M" @! P% g2 p bool m_bServiceStartedByEmule;
- @/ s; K1 q8 f; G. f bool m_bDisableWANIPSetup;
" ?: e2 A- n3 Q bool m_bDisableWANPPPSetup;
$ ~% h: L$ f6 h& F, u% i9 B; L: z c
8 u2 \) W$ v6 i: c8 `# [$ S/ g4 @3 q. N! L9 I" X
};1 g: x m9 @6 {& m9 r& z
5 a( ]1 I% h+ I
8 _ Y* h1 p A// DeviceFinder Callback
9 Q% e1 ?9 K; f/ ^, h" ?( fclass CDeviceFinderCallback3 E6 a& L3 E: D/ i, k+ T+ Q
: public IUPnPDeviceFinderCallback5 p. \; [- y( M( H/ s
{5 o; [( ?, F* I: A) F7 I; B& y
public:
+ y1 m. ]9 v, U% c3 L3 s; g CDeviceFinderCallback(CUPnPImplWinServ& instance)7 t/ ?3 \9 C! l7 s9 Z
: m_instance( instance )' j, ]$ y- N" h8 w
{ m_lRefCount = 0; }
( c8 W. g. S. X& P# }3 u @) ^3 x
+ g% X( o! x5 S$ n, M
, d! ?: R- T$ G: c2 {0 \: P. l# I STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);, A$ B9 Z1 g* q2 q2 J5 R
STDMETHODIMP_(ULONG) AddRef();( W& Y+ E; B3 K; `
STDMETHODIMP_(ULONG) Release();
, m5 f! @; x6 }* U8 F
+ Q. a }" n8 R o1 \! E/ N& ~* @) L0 _7 b) m4 d' N
// implementation
9 L, a( p, n1 J- D. ]# Sprivate:6 I/ g: U5 Y1 r& S
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice); t$ [+ @% C1 L
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
& L9 n9 G2 U" l- m HRESULT __stdcall SearchComplete(LONG nFindData);
3 N4 F- O6 j# L: y
. U8 ~: a3 A3 I B# F6 F B4 [: {3 W# r7 `* ]
private:+ H3 P( A2 o4 a7 d. A& D5 q3 s1 q! q
CUPnPImplWinServ& m_instance; l( U6 e- A" G0 R
LONG m_lRefCount;8 W0 z3 E! B& N ~" J
};, k* X" V) O7 L, H
$ O6 j' G' e5 p" t, f/ Q2 ]
/ z& o& J* L) d
// Service Callback : S) f$ X" {8 q! v1 _ A
class CServiceCallback
- k( R/ O0 t! @/ d6 {. G : public IUPnPServiceCallback
+ s l4 k7 H5 P: c; o8 |9 ?{) ?: U2 _8 j1 H
public:- l6 ~& L( L" E! x% p7 h" O
CServiceCallback(CUPnPImplWinServ& instance)
( W$ M% R. p3 S : m_instance( instance )% N# k" t3 E$ k8 C8 s/ Y
{ m_lRefCount = 0; }
0 B' [; [( E/ [& S$ u+ S q# ~" v' F& k k. E: ~$ C
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);1 S R; m. M$ U( g; \# {, P
STDMETHODIMP_(ULONG) AddRef();
1 y$ a D: C) i M) P& i STDMETHODIMP_(ULONG) Release();
' ^: _& v, O) Y! t9 Z+ I2 X0 r7 u1 B, H) ]# z
! @8 y2 G! M! Y, x5 M// implementation
5 t E) k$ \7 f% B5 yprivate:! b8 y% i% U- L9 w0 j: {: D
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
K- j% s \4 z/ I* A HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);3 `$ G; g1 u4 X& Z: j
6 @- Q+ M% \* ^
6 p' l( Z2 @0 ?private:
2 R y1 p5 c5 ?7 ?$ n5 A4 y0 B; { CUPnPImplWinServ& m_instance;% s8 x4 v( H% ^2 e A7 K% ~* J
LONG m_lRefCount;
% t: W3 t" _0 ?/ ^" k. y @1 ?8 `};
4 Y7 ~5 t* K$ M; e3 W4 O( Q. V9 h* g. y* p) o4 d8 U6 m# }) d
0 k" e) ~& N+ {1 Z u! V! H/////////////////////////////////////////////////- E, G' A; ?$ E0 K
4 `# W9 m6 c7 [' ~' `/ W
3 w3 A, r9 U" v& ^6 T
使用时只需要使用抽象类的接口。. d# t" Q8 Z/ y3 g5 r Y1 C% o( w* f
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.; r# a6 e" ]; ~* k$ m2 W
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
6 ?9 u$ j+ y& _8 P4 q; ~CUPnPImpl::StopAsyncFind停止设备查找." Y' T2 k3 d/ b
CUPnPImpl::DeletePorts删除端口映射. |
|