|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
8 O+ r* U5 ^# @0 }+ F" Q0 e, B' X* t1 F4 C# m
- \2 Z, k' t3 p9 ^* S7 z& q: D! j///////////////////////////////////////////+ {6 ~; L7 C4 s: [2 T
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.2 V8 g2 l) `8 `
$ }/ _& W3 N S9 _* W$ ~! E' l
( M |+ h. O( n+ w
#pragma once
( {. q u, }) \- `% U) [#include <exception>) N) ^$ z/ e9 {* n
2 j$ q/ w! a+ b# H& \% p* L8 [' `
( y" J. e; g q% m$ @6 _ enum TRISTATE{! z7 i. J4 q ~- w3 g2 g/ e, ]
TRIS_FALSE,
6 B# Z; s$ D% \$ r2 f, a TRIS_UNKNOWN," l6 W+ z5 x% P; ^" }/ C
TRIS_TRUE% `: i9 p+ L7 s1 h
};
4 Z. ?7 C/ c9 j d3 r5 `1 ?9 `
/ d4 m" k, L1 _0 l# k! y- M
/ R( O% {$ C# W, I' h \# @' kenum UPNP_IMPLEMENTATION{
5 V4 ^2 `& v& t- @7 \ z [ UPNP_IMPL_WINDOWSERVICE = 0,% _+ _1 P3 F2 Q q
UPNP_IMPL_MINIUPNPLIB,7 p9 A. m/ O. k* Z6 v
UPNP_IMPL_NONE /*last*/
: ~( v, Z: o) a( j4 T};* s7 j& u: r9 ]( x, j
3 T6 C5 t7 I) N& m, W2 k
1 V- J8 a. {% w- e, _6 S8 E
1 c) E0 _# m. i9 F0 p; }$ ^, [ B! o( p3 ^/ a. n. H
class CUPnPImpl
. E0 F# K+ C* J* a2 s{
2 _. _6 A2 T7 l, ^& Epublic:
4 U) `3 o7 }1 u, z K CUPnPImpl();1 s0 X# \, X/ ~2 M. p( D/ Z0 `! T% V
virtual ~CUPnPImpl();3 o8 |' D/ q* f9 ~/ U5 T0 m# g
struct UPnPError : std::exception {};: e M- P' `8 S/ N
enum {
" N) ]1 z( O+ R7 L' u UPNP_OK,
- s2 \; `, l9 Y% p) I j* W; q2 ^ UPNP_FAILED,0 D( J$ w, q& X9 b2 G
UPNP_TIMEOUT) L. a) W# J2 r+ K3 O
};
' P/ d# ` k2 {% _/ L
9 Y& ^# x" x5 @0 @8 F, W
6 J6 }3 Z9 [( g virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;, p8 D$ a1 N _# c9 U" u
virtual bool CheckAndRefresh() = 0;" t# v$ p9 x% \( e; u
virtual void StopAsyncFind() = 0;# K, i; I: X: w1 m$ T2 M8 u
virtual void DeletePorts() = 0;
+ _: i0 Y( D* f virtual bool IsReady() = 0;
3 f) B m1 l8 g: ?; V: h$ _6 u virtual int GetImplementationID() = 0;7 b0 Y3 Z; w5 y( f# ?" l5 y
$ I0 q8 V" x* ] x void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping! C; X" p- I; d) [9 J3 }4 W
6 K5 k# W2 u6 x B5 v% u& d9 w
+ L, p- H* m; R1 ]( n' F8 u- }
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
6 T' ?6 e- o* X3 z9 q" i2 [& |; E TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
+ o& L. s: |3 m) A# o! N uint16 GetUsedTCPPort() { return m_nTCPPort; }, i7 g7 t& J }$ ~
uint16 GetUsedUDPPort() { return m_nUDPPort; }
! R; i4 o" f9 C' _% z
1 D3 m3 v1 d) i* j
2 W3 B1 Z9 l* x; }# Y h; e// Implementation
0 o; ]- D. x2 ?2 }! t4 {protected:
: f5 f( ~+ u0 N; B- P volatile TRISTATE m_bUPnPPortsForwarded;; A* t% @4 T/ F9 J* y
void SendResultMessage();
; A. j2 l3 X, U. H3 t uint16 m_nUDPPort;
. v6 I, e( g2 D( m+ V" O uint16 m_nTCPPort;% u5 i& r2 J8 f X6 O
uint16 m_nTCPWebPort;
6 Z5 Q7 a6 b- P1 ~- Q bool m_bCheckAndRefresh;
5 A9 [' M: S3 W2 y( \+ Q1 U% f$ M
" A8 m4 X/ ]/ |0 B0 w
+ u+ R& b5 r3 V% [* fprivate:
( Z/ {. d; d9 j+ x% H8 D HWND m_hResultMessageWindow;
$ N8 x4 D1 F- O( J UINT m_nResultMessageID;
5 H5 F% {; w2 ~# g) S& C- _
9 O& ?: q# {! Q; l& o. f& a( C/ \; M6 ^7 s( ^5 Q; j
};! J7 b/ N4 h. ?, K" Z6 e
' C# L1 m0 g1 J4 C5 C5 E( g, [2 l# X9 @1 Z9 a; q
// Dummy Implementation to be used when no other implementation is available
9 `/ K1 v- t R, Eclass CUPnPImplNone: public CUPnPImpl0 T$ y9 O9 J$ k9 |; c
{
# F6 A0 T' `& W# {, g6 u* Jpublic:
5 F$ q; W) e% g7 X7 V0 x( J virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
2 A6 A: X. ], ^& \2 o virtual bool CheckAndRefresh() { return false; }
6 @/ }7 D4 r) ^. R virtual void StopAsyncFind() { }2 ], i7 d1 ~5 w/ o h
virtual void DeletePorts() { }
5 t, o. z1 R) ~$ ^! K5 y virtual bool IsReady() { return false; }/ Z: e( O" G9 z9 h0 p
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }0 {# R) K0 r! A, H) j: |
};, D5 N' |1 G: }
4 A: u' Z; ^% a( B0 c8 M& Y: G, {6 X- B" n
/////////////////////////////////////
3 C5 v/ v; O! |) b& j% E4 ?//下面是使用windows操作系统自带的UPNP功能的子类9 ?8 r/ R6 f+ v: X1 e
* I( m* L8 G* Z* Y
5 g* ^$ z( ]- n" w Y1 j) v7 K: J#pragma once
- u3 T" q2 C& ^' I2 D" s) R#pragma warning( disable: 4355 )( Q. [; h& @8 Q: x- t8 m
f) I; l- Z- t" r+ [
$ S6 e& p4 i( z
#include "UPnPImpl.h"
. f. f$ B: Q, i+ x7 _#include <upnp.h>$ z7 C# J( m4 m$ S, K4 B2 _
#include <iphlpapi.h>
! s7 p+ b _- e; Y$ ~4 D#include <comdef.h>, ?& ^, I5 k1 c9 H" q
#include <winsvc.h>0 ^3 `; L' a" l: V3 k; E: A# m8 H
) X3 m- u# B' t& [+ A8 o6 k% u4 b, ~& d. o# t7 n" F7 Q0 C$ y2 K
#include <vector>. D3 t! `- D- o O5 D5 W1 L3 v
#include <exception>
* P3 S9 G a I, l) H#include <functional>+ I6 _8 p& z3 z/ \5 }
& W7 P$ y, e, ~6 E9 ]0 P# h* W C" T+ E1 N9 N; z4 f& M
/ h7 B% B7 {( G
& }1 Q: R6 o9 I- |. e& d* ytypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;6 l7 `, ^& r" a+ b. e
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;8 X7 @6 f7 |& f! Z" e' j( y
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
* Z* B e7 R( W1 Xtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
$ U4 F. Q7 M% B ?0 K! k9 i \# Ptypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;- J: r \# g2 [+ j9 @" q
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
' G1 ^& j B: h+ m) p9 z- L6 Jtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;- j7 R% z- E u. k% v4 n
- l6 F0 [7 B; e' p. @- X) s |0 q
4 a2 o" y ~! Ntypedef DWORD (WINAPI* TGetBestInterface) (% Y* y/ W( F/ A& @
IPAddr dwDestAddr,
- Q8 e$ B# r4 F- ~5 e( G7 q PDWORD pdwBestIfIndex9 N$ e% [- ?, R/ @( D. c) S
);
) s+ n8 F$ L5 E2 r7 d# g, j/ Z5 \' n
. w* c* |7 R Y) H* K0 C2 @6 K$ u A' I1 S9 M3 t q% @4 E+ B
typedef DWORD (WINAPI* TGetIpAddrTable) (4 w& S7 ~/ @% N# k
PMIB_IPADDRTABLE pIpAddrTable,
6 s/ l3 t; v. v7 u2 X PULONG pdwSize,5 d" b$ i7 N* {6 ~( r8 T
BOOL bOrder
& a1 w' q$ }( c# s);$ P7 L/ [1 J3 H2 c0 N" I
& O; D3 A4 U$ Q
- w0 \4 b* t$ S; G& ^9 ]* z: S
typedef DWORD (WINAPI* TGetIfEntry) (" v! A {3 d* `2 G2 m6 Z
PMIB_IFROW pIfRow' x# B) r* a6 t8 ?; F' Q* k; r2 ]
);* V7 L' q3 w# W4 f
' a4 q0 r% E! k$ L z) J
8 q! U$ u8 z9 ?4 n& |& i3 ECString translateUPnPResult(HRESULT hr);4 k. L3 x6 }# @7 |; v6 o& I' }
HRESULT UPnPMessage(HRESULT hr);, v4 k: R% N- {5 ~
( q; o, ]0 R8 b
: Y- k6 U! z) V5 i/ Jclass CUPnPImplWinServ: public CUPnPImpl) z5 O8 \/ W$ w3 K5 R# z
{2 j1 V( P( {/ _( j0 Q
friend class CDeviceFinderCallback;
& ~) l& ~* @' F( ?" M' A; C$ q friend class CServiceCallback;" ], F$ E- `( k- h4 F
// Construction) a. t* W) w& |2 p7 t! n
public:& X) z. c: Q" Y- ^
virtual ~CUPnPImplWinServ();
3 @6 n: F9 y/ T* L, s ]7 n( f1 V CUPnPImplWinServ();) z% B# Y; J! s0 H, [
( x7 n9 ^" L. E% Q) k! j* g2 R5 f5 F3 a6 M/ Y: X0 m9 _
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
6 B& L- K, w3 T0 ]) E( k0 n( R virtual void StopAsyncFind();
4 D1 k0 k- ~9 Q& Q! I, O6 \) G virtual void DeletePorts();
- e7 y. S) W- C+ L: l virtual bool IsReady();; h6 T4 T' ?8 N2 a0 B, X$ |
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
7 F/ b1 S; M {
' L- x) u) Y5 {1 P9 E* |0 ]8 h' E$ P: \2 t+ |6 s& V$ R+ f" x/ n
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)/ Q7 M- s: R9 b8 Q, } ]$ {* T) m
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later/ c$ o0 N5 i4 k6 p! f
virtual bool CheckAndRefresh() { return false; };
: B1 f; \; @$ z) _2 t
8 f3 Q: ?# n& z% k3 Z/ l' | F* `7 ?6 o: M0 L
protected:2 t- k+ D: R2 b. a" x Y& v+ E
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
& y4 @$ `$ y8 n- k$ w2 h) v void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
* v( G3 x9 [5 ]( S+ g void RemoveDevice(CComBSTR bsUDN);; z' j; h5 {4 F$ N! Z
bool OnSearchComplete();/ c1 Y6 Z/ P, }4 R6 [ {
void Init();
4 O8 `% C# _ q% R' X6 i, `. y
Z+ F% o: Z7 L3 t, c
$ V# x1 s5 l. ?8 H2 b6 J- p inline bool IsAsyncFindRunning() $ _% v3 _3 S; C+ y
{& K1 b5 h7 a/ ?- q; G8 f
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )7 g/ {4 r1 a& G! e" `9 l
{+ P" I5 l6 q2 j; f
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );* `" \! J1 o9 I6 C' V h! j: k
m_bAsyncFindRunning = false;/ _4 X2 v# V0 S+ n N7 I* A4 c4 s
}
- n/ ^" a% Y6 v8 l1 | MSG msg;
' \( c( q3 a' T& V0 p( N while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
* |. [' l9 H+ x1 M& t$ n; s {
7 Q( M6 `2 e2 u6 @: _0 ~' K TranslateMessage( &msg );( k8 f, Z* y! M" T* L# m6 ?' E
DispatchMessage( &msg ); t* }& k/ T. w( @! F" C" L" T
}6 @% D8 W. u" u2 ]- w# J# Z: T
return m_bAsyncFindRunning;
7 M# [* m% M2 W3 }4 S1 R }9 @/ o# V& K, i( c3 s
% ?( U% A) _6 m
% j, P& D( c6 k5 H, F$ [ TRISTATE m_bUPnPDeviceConnected; i/ p& s) \* I" Y0 @9 m& I% M; z
- N" i3 v6 Y% h- W7 M% J/ s! V2 ^
, \* ]4 e/ h& d! A/ m// Implementation$ ^$ X1 V* ]' F+ J* [
// API functions" C% T% q6 v0 d
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);( N7 R' U, }3 n' t1 l6 ^+ F
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
4 L5 N3 I& \8 z& O BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);% T0 R/ a3 _! o. q
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
$ u% ?1 z. i% j4 ^& ]" A2 w8 ~% _ BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
& O' [2 r. V' Z7 d% q BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);/ {% i, t8 R+ `5 x9 l. O- s! a3 v/ @
* s4 j5 U' c# N2 g. T" u6 J. K0 f, z. s
/ ^0 T! l; m- f2 F6 O+ F TGetBestInterface m_pfGetBestInterface;
0 {( N8 m8 O- I! R( H2 U% \ TGetIpAddrTable m_pfGetIpAddrTable;$ D$ B6 f& k s/ u# @2 h
TGetIfEntry m_pfGetIfEntry;; X; O9 Q h( f& C1 M, O: }
' s( j: x& D+ G* o, o, ]! y! M+ _! `
static FinderPointer CreateFinderInstance();* W! W5 {; ~) w" s+ O3 w
struct FindDevice : std::unary_function< DevicePointer, bool >, I$ K' a1 u1 Y( H
{- l& E% g% o6 M" Z& [1 {
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}1 E3 x6 M. ~/ {% C4 z
result_type operator()(argument_type device) const
# l9 ]0 L- z6 v5 f! p. x# L/ M {' i4 A: w+ w! ?
CComBSTR deviceName;/ o5 O, M. G5 b, m
HRESULT hr = device->get_UniqueDeviceName( &deviceName );0 n f; g! @% }/ d& A) G" K( C* w
! g I4 ~/ }9 }& [4 W$ `
0 b1 F& K! A7 Z6 i5 [
if ( FAILED( hr ) ). Z- F% r- ]) S2 D/ m' I
return UPnPMessage( hr ), false;+ r4 K% \/ k @
# I' _* K8 k6 U2 [! s: h* o7 U" q# B, ^% m8 K9 S
return wcscmp( deviceName.m_str, m_udn ) == 0;+ M8 @# r! f& S" r' B/ H: R3 M( F
}, j, w9 \3 A% t9 A8 ~+ {. V$ o9 K
CComBSTR m_udn;
/ C$ s. R2 R' u6 Q+ H' x# S };1 s J, V% x# h5 {( G
6 a" ?, M0 v. K* E
void ProcessAsyncFind(CComBSTR bsSearchType);& K. Y4 P$ ^3 [% [; ?
HRESULT GetDeviceServices(DevicePointer pDevice);
& @1 A: A3 d2 B% Q$ ^& w void StartPortMapping();
0 @( m3 E: Q t" W( J HRESULT MapPort(const ServicePointer& service);$ U, s3 m0 g4 k+ \
void DeleteExistingPortMappings(ServicePointer pService); h3 r" k0 H! F" A, E
void CreatePortMappings(ServicePointer pService);9 @! i% p* ?& u2 X
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);/ P+ M; d0 V- b2 D
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, . H6 [0 |9 A/ M& r/ s9 J4 p' N
LPCTSTR pszInArgString, CString& strResult);
! F, p1 n5 E0 | Q2 I' K void StopUPnPService();$ q/ X% D1 }5 N& _0 W: b/ ]
1 ^" B0 J, i1 y+ U0 v& A; d
4 [, Z' l2 W) F8 P4 _# R, G5 K9 w // Utility functions
* H4 u, X3 A$ ^" y" d$ W HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
! S5 [' c ]# S3 |& s INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
5 v7 _: @8 j% n& Z INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
! P4 H. H' T4 a/ ^& c& i void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);2 ~% B* Z+ t2 ~8 \% y
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
; A5 J- \1 p# W/ h( y HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
* l x B# @5 b" z; B3 ]1 @, } CString GetLocalRoutableIP(ServicePointer pService);. d: D% h0 g1 m7 A9 }9 G; s) Z
8 G* b: R# I8 a; v6 ?$ ?0 C' @: d8 Z, e" Y
// Private members
% e* z9 v- C0 Z* N# c/ s* \private: X/ f1 ^0 P" v5 F; N: a
DWORD m_tLastEvent; // When the last event was received?
# X- Y7 W2 f) E- g4 x std::vector< DevicePointer > m_pDevices;
3 D8 L% D, o2 \ std::vector< ServicePointer > m_pServices;
0 M6 b: ?7 K- J; z: [9 w' Z/ b FinderPointer m_pDeviceFinder;
" s$ N8 G2 G3 B: w DeviceFinderCallback m_pDeviceFinderCallback;
+ q8 P: n! S# k% B ServiceCallback m_pServiceCallback;9 j4 @# q8 j! T" }3 S, v4 G5 }
/ ^; }" s3 f$ v w; o1 n; v
3 L6 q. D% W" t# P4 T3 \3 n
LONG m_nAsyncFindHandle;( m6 q( v9 p7 \5 B2 D
bool m_bCOM;
- j# x: \$ m( c& S bool m_bPortIsFree; Z0 L) L- y7 J$ A
CString m_sLocalIP;
7 Y3 Z- _- c6 R b" b# @5 G CString m_sExternalIP;
. Q8 H, M8 o( e/ D bool m_bADSL; // Is the device ADSL?
3 V4 R y9 [1 m. @7 L/ Y bool m_ADSLFailed; // Did port mapping failed for the ADSL device?: w9 Q+ Y( W: ~% N
bool m_bInited;
* f5 z) i8 }/ G2 Y, z# I bool m_bAsyncFindRunning;
* A1 `3 V3 N& c' r7 J HMODULE m_hADVAPI32_DLL;
[9 v- A' O$ B5 c, m HMODULE m_hIPHLPAPI_DLL;* o o: u; b1 x1 T2 E+ [* M
bool m_bSecondTry;$ M* J/ W; t0 q: G! k( ~1 `
bool m_bServiceStartedByEmule;
9 a4 J, R2 G5 u8 P o bool m_bDisableWANIPSetup; N7 K& }+ {! L, @5 p
bool m_bDisableWANPPPSetup;( O9 r# n3 b! G& G5 K7 V0 Z
5 v9 h1 D3 M" Q0 o) a. N
8 b/ K) U4 J' p, c( N+ D- c2 ?9 H" c+ w};
/ P) L) p& P# [$ k: Z, m
6 J, W& G4 f/ c; F* C, c3 T6 i Z @2 V' e- `
// DeviceFinder Callback
- O8 b2 m- R4 eclass CDeviceFinderCallback
: Y! M" H: a. E' S2 k- a: ~( N : public IUPnPDeviceFinderCallback
: J" r9 K" _! n- l$ Q7 m{
% X7 n8 b$ s# g% N; W7 Jpublic:
8 s; X* }, J& G* G8 x# P CDeviceFinderCallback(CUPnPImplWinServ& instance)) t( y0 q! K3 ]7 Q
: m_instance( instance )
& ^ F! _: t$ Q- H8 _7 Z { m_lRefCount = 0; }
- a. @+ y- ?% y- k/ h1 n
0 E7 I" p) g$ L1 X5 H$ x" L" x' `9 r& M: ?# ?8 G4 f6 |
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);5 a) T0 L* I& b+ S8 y
STDMETHODIMP_(ULONG) AddRef();+ Y5 b, x& q7 r" H, O8 x- s
STDMETHODIMP_(ULONG) Release();9 Q! a7 Y' ~! s$ a( Z% c5 Z
/ U4 a6 [" z: u, p
$ [* ]8 L- [' m; F& f; K+ Q3 O( i// implementation; a8 U& s; ~5 g% ]% p4 f
private:+ V! F1 o | u% y
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);+ t+ X! _% m. _' w+ V
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);5 g) s, h- y, c. N4 Q
HRESULT __stdcall SearchComplete(LONG nFindData);6 i. L9 L$ n8 o! o$ i
]. z. g0 @: T' d0 F( H
8 i2 n( C" `: s
private:
6 ]. ] z+ v( v) ~! @ CUPnPImplWinServ& m_instance;0 n. [% R$ }1 p) `2 ]
LONG m_lRefCount;
- y# {& m H b" C' a3 M};
& ?: B) n6 b. |, `' f. a, K5 S6 ]* P4 o
+ a( h9 x2 z2 ?: w" w- f2 C// Service Callback : z+ H: y* f* y- a# E
class CServiceCallback
- n2 o [; {' |/ P& P# Y: n$ D9 o : public IUPnPServiceCallback
% o2 p z: M; \4 ^{
! d- M7 M& ~6 w8 t1 L+ k( z% |8 Npublic:
1 a1 f) Z( |8 x, _6 | CServiceCallback(CUPnPImplWinServ& instance), T- s. F& e* Y
: m_instance( instance )6 b$ F$ {0 u3 U$ T1 n: S
{ m_lRefCount = 0; }& ~# n/ p. F+ q) G3 |" |) H
- G. Z5 _. `9 i
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);. U8 s% W7 J% u5 {
STDMETHODIMP_(ULONG) AddRef();% W4 d7 q# O9 z
STDMETHODIMP_(ULONG) Release();
$ _" E) Z6 J, u* O
& P! u$ K' z; [% V
J( \# x$ H1 t/ ^: r+ Z// implementation% L7 n. A9 B. Y: k
private:
$ o; ^8 j$ v' g& e3 g6 ]3 ^9 U4 d R+ L HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);( R4 B( B# r3 X" h3 V
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
! F6 N% u1 i! \! o" p+ V' @4 P5 [ d! W' S2 a
! m- S6 D1 `) ?1 Y" o
private:+ u: K7 i9 ~, u/ N- h4 F: b
CUPnPImplWinServ& m_instance;
) T! Z& ^, I% n8 y. _ LONG m_lRefCount;3 N/ q% \0 Z" l k) I) j
};4 q0 M: E4 @# l4 k
. p/ g6 ?. L7 g+ P1 M p
. F7 u8 M! U+ g1 A/ \/////////////////////////////////////////////////+ W/ W+ ? m) x4 u' v- B1 M7 Y& I
3 u0 h' e: t1 e( Q
: @, l) t {" }2 A# r) N+ k& r
使用时只需要使用抽象类的接口。) I9 t. }- }1 x" {# I
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
% o1 ~3 S+ Y' C& bCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
0 n% `# q( N5 o3 bCUPnPImpl::StopAsyncFind停止设备查找." w' p) t. H8 v3 _: [7 K
CUPnPImpl::DeletePorts删除端口映射. |
|