|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
6 N0 l0 q c$ `7 x# Z$ o, @" x: S' x3 ]# N. @
, a; j% ]2 y2 d" r# _$ } l/ P
///////////////////////////////////////////8 M# T1 J. @" ^5 Z
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.- z8 z$ ]) O8 E$ ~7 n" B
2 W8 K/ G3 _# ]9 k% _6 E/ Y
* j. v. H; ~# ]$ q#pragma once. L9 T2 u: l# w) P. b3 N/ B& G, |
#include <exception>% S0 H5 f. O0 Q
9 e; N2 j. j! \# P
; h8 ?0 O8 ]/ h" a8 o$ i& K( p8 ^0 h1 G
enum TRISTATE{6 o) I1 j7 D% I; X/ n9 p2 U
TRIS_FALSE,/ X, l. c' `, e d
TRIS_UNKNOWN,5 W" {% p7 d( c( ^" F; c- Z9 q6 R
TRIS_TRUE
2 A. a( ]9 w H/ |};
5 C6 P$ D9 p" ^3 |- T6 _# _( x% A
F z" F. j: k9 l _; R& R! i; c; d* F/ X8 N( {4 e, S
enum UPNP_IMPLEMENTATION{
) s r" L2 s% L UPNP_IMPL_WINDOWSERVICE = 0,( r0 u3 S6 K2 `
UPNP_IMPL_MINIUPNPLIB,2 i; X! ]6 M, U& {6 v
UPNP_IMPL_NONE /*last*/
" ?7 c+ q* t" ]* H9 G};
5 ?4 I! F& c4 ?7 A; F7 p( o, t" J+ U+ p4 \
. C8 m, m- [& U3 R; B
# x9 b- M" G7 G0 f7 s2 J' ^7 t7 G0 A$ x0 L) N
class CUPnPImpl, \1 H: x3 H* M+ v5 ^
{3 j* W& D: e: S9 w$ Z. {+ R! f3 ?
public:
1 \. Q) R8 d) y2 G0 K CUPnPImpl();
\/ c/ N" Y2 u! E virtual ~CUPnPImpl();7 F! T5 m9 S5 Z W9 {2 C" P
struct UPnPError : std::exception {};
/ [5 A# h* m# ]% _) C e# Q7 d. f$ {& A enum {
# I. Z6 i; N! X M) {- D9 a6 I: c UPNP_OK,4 ^4 R- [9 L6 ^5 ^
UPNP_FAILED,
. k# e) K$ `+ \# ` UPNP_TIMEOUT
8 A- T* N- \" ~# E! L };
# C! x. x, P' X# n* y
0 O% r( J% O3 `& @8 `3 i2 r1 [! O6 X
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;; {9 l! [/ X' ?2 |/ U2 }' x
virtual bool CheckAndRefresh() = 0;
9 r8 d+ F- ?; C# R( V virtual void StopAsyncFind() = 0;" c& N% v3 D5 u$ u- L( S
virtual void DeletePorts() = 0;
# e4 @0 Q! n' O/ G! O' c0 N9 N virtual bool IsReady() = 0;
1 t u' h# G8 b# J, j$ k* @- m% g virtual int GetImplementationID() = 0;
4 ^& I8 Y7 v+ L4 n* L# d) Z 8 I1 B; ]* A" h$ P, k) `1 \
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
9 n2 L, W. ~1 c0 K% M3 i0 r3 I- o; A; L8 o& n5 V2 q3 x h9 R, C2 X
$ R4 }0 @. p) u9 J$ d void SetMessageOnResult(HWND hWindow, UINT nMessageID);
% U! `7 e- E1 Q1 d( L- d TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }8 |0 p8 |3 D+ D g' T6 x/ h
uint16 GetUsedTCPPort() { return m_nTCPPort; }2 W- Q' N, G7 B* x3 M) T
uint16 GetUsedUDPPort() { return m_nUDPPort; }
0 E2 d* A5 I7 _# | i, r' `5 d% | D0 s# L$ w0 i. V/ T
+ n( e B$ W4 p2 o
// Implementation
7 [% M' ~- C( G0 I7 a3 s' rprotected:* H$ \" R- ~2 Q- U
volatile TRISTATE m_bUPnPPortsForwarded;
/ ~- J3 ~/ @2 O, L void SendResultMessage();
1 d/ [0 s- e9 u6 X, x5 ] uint16 m_nUDPPort;, @- w( D0 X4 a7 v
uint16 m_nTCPPort;; }) K$ j+ r5 U3 }# [
uint16 m_nTCPWebPort;; `) q- p9 @( Y0 o+ V
bool m_bCheckAndRefresh;
+ x3 M, f+ G7 Q% U% s
: {7 d1 [1 X$ d+ g \: n' w |% t5 s4 T/ |. a, ]4 X$ J
private:$ j. j6 h4 w+ [) k+ P% n
HWND m_hResultMessageWindow;
! U0 I# w- y# e3 Z* w+ I% N: L0 y# u- h UINT m_nResultMessageID;+ S! v# j y) L
& Z1 ?7 f s8 n
) {$ V2 s+ N7 x: m8 k. |
};
4 z+ H. P& {, e4 \2 G' a+ v3 J8 C& m2 k' z- F2 }1 [* Q
) a/ ^0 E1 r" L7 M// Dummy Implementation to be used when no other implementation is available6 n$ O9 S1 Z2 k0 x
class CUPnPImplNone: public CUPnPImpl: u1 I( _/ ~. D& ~
{
, m0 K2 l1 Z* S4 s! x8 A, ~- V8 B) qpublic:7 c! e/ {; G- q0 s
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
/ O; V' z( `8 w& k _. I+ S virtual bool CheckAndRefresh() { return false; }. P; z# n! G0 M; {8 ?
virtual void StopAsyncFind() { }" K, t N5 A1 Q3 z2 z: S& _5 L
virtual void DeletePorts() { }
6 _2 g# M, z2 F7 o+ Q/ d! V" t: F virtual bool IsReady() { return false; }
( @ ^- u6 P& R: c+ n2 F virtual int GetImplementationID() { return UPNP_IMPL_NONE; }) c" r: F) R k( a) o( \
};6 S- T% |2 T7 \& Q. J3 P$ P: H
% ~4 ^. j. ~% N% E" g9 L' R: I
6 ]' P: a9 `- B9 F% P# {, v* H/////////////////////////////////////7 k* Y7 `* B% ?& k7 l" a- ?( @
//下面是使用windows操作系统自带的UPNP功能的子类8 m7 B8 j, I$ \: O) O, ^, W: b
0 Y: G; o+ ]9 M9 H2 _/ a' h8 E4 D* v5 l# L
#pragma once
4 l7 b! B( u3 o+ }#pragma warning( disable: 4355 )8 k, {4 z; C) X
% Y, k. f' a4 F' k: {9 g
: @' \ ?" A4 E' s
#include "UPnPImpl.h"9 A( x8 y2 a# C5 ~; ]/ S
#include <upnp.h>2 m. a/ V' ]3 }1 ~) b
#include <iphlpapi.h>( W5 N6 L0 B2 ^; W$ Q# t
#include <comdef.h>
& _% Q& G# t% J/ n#include <winsvc.h>
, X! `( b& r' x I6 s
2 R8 F- T$ e& P, k+ X4 ~. v. G3 F
#include <vector>
# g7 ^" V& N* V q#include <exception>
; N' W* f3 q7 o E$ m#include <functional>; K2 p% V6 _/ C2 c u
7 P9 ]& Z( k- F+ ]( N8 J* S9 b O. }& ~
$ T6 Q& j3 D7 T8 }6 L
6 y& A1 t/ U! [( j6 j
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
% W/ U5 r4 c- B+ k7 mtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;) w9 Q* W+ q" D
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
/ y; E6 y5 k3 A* r; H7 D% Gtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;! r' C' D4 z8 i" f
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
7 S) {- z2 S9 C$ F2 ftypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr; d: q, N0 S# W) L9 d
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
% r6 \0 n* Y9 J; H4 {8 D: r V" q
) g2 }; @& M- a9 ~: ?
typedef DWORD (WINAPI* TGetBestInterface) (* A: f7 B" f1 j8 S3 G, C+ B& K, S
IPAddr dwDestAddr,
6 q7 s% l& Z f' I& T( M7 m6 o PDWORD pdwBestIfIndex
+ M' v: v( W! O);0 ^3 e5 b: V& L. a3 a0 R" D p" l
8 H, g# R% q+ I7 {
0 ]# G1 |) Q5 J' y( t" ktypedef DWORD (WINAPI* TGetIpAddrTable) (7 ]% q) A" E0 c! a
PMIB_IPADDRTABLE pIpAddrTable,$ }- ?5 ]6 m9 S7 T9 w4 P1 b
PULONG pdwSize,
! z2 M0 m" T: g R, H! g BOOL bOrder
5 H& \. X* F0 z. h/ M);' u8 f6 `1 J8 U* N8 y( O- P! P3 P
' V% ]! _6 U/ [* u+ v& q% ~$ i, D
7 s- i3 c x q+ R/ Atypedef DWORD (WINAPI* TGetIfEntry) (/ v/ X' ?2 f& b
PMIB_IFROW pIfRow6 b, s! F" i: ^4 e2 C3 |
);9 Y9 G R/ r. l. f; s# l6 ]: K
9 r6 s8 b3 b2 G: m, h& X
- ]9 p: o% s5 j5 r' f' g, J' {1 b
CString translateUPnPResult(HRESULT hr);8 j7 m& B; {; w/ i- |& U) I* a
HRESULT UPnPMessage(HRESULT hr);0 F" P& d5 N2 S, |* A
' \0 Y% r _/ J8 P* C9 r5 e' N$ t: A! B, c, J
class CUPnPImplWinServ: public CUPnPImpl
! o; O) V0 G) f/ T9 S0 b. n. v{8 e$ K( W$ x* ?0 [- t
friend class CDeviceFinderCallback;8 k" Z# x+ g1 h
friend class CServiceCallback;
4 U+ Z F" {, O3 y// Construction/ K) v; K( ?# Z" V$ K: _* o- I
public:" b% Z+ z, `' ~1 c* v3 z
virtual ~CUPnPImplWinServ();
: D% E, K6 |( a' _5 @ CUPnPImplWinServ();% P0 P( b* i1 u) ?
+ u6 ]. U& M6 u
& O3 o0 ~$ x: B- D virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }( @0 y0 W) v- o/ I! }
virtual void StopAsyncFind();
& W! D' Y* D0 B virtual void DeletePorts();
1 N* N' t* V" D. Q" Q virtual bool IsReady();. H) S0 _ \" i, K( @* Q$ `
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
' t& s' `* H$ c f
6 ]' c8 u: [( {5 y Z/ H2 `2 T" _' o
6 r( y3 _* o. L. [8 H, R8 [9 t0 [ // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
0 M6 r7 J% `* G. x# \ D // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later* a, x% I3 t; C1 `" n6 C& h1 x& h
virtual bool CheckAndRefresh() { return false; };
7 Z( |' G3 x5 U1 Y- j( D5 N! u# ?* z! c) a5 W
V6 x6 f( C' U/ A( B6 J. j7 C+ \protected:
4 w( `. s0 e5 ^+ p& N6 U void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);' i/ q! T# z' B
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);, ~$ [ A0 A; g1 @
void RemoveDevice(CComBSTR bsUDN);
0 i0 Y. M/ @6 H5 V, F. @; O bool OnSearchComplete();4 F* m7 f: c7 @2 }
void Init();
! o/ \5 t; |) q: r3 g/ m
4 f- j, T' n8 Y' X% d5 o1 D& S" e) ~2 p+ _' K' R' I( v% B* z2 Z
inline bool IsAsyncFindRunning()
2 X+ |. x- x9 D {
- o! Q6 [" w1 O+ W if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )9 n: A6 P; @" w; ~( |; @0 H# {
{
9 Y' L$ O8 ?3 ?( I/ Z9 n m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
) h) q5 I8 |( B m_bAsyncFindRunning = false;3 t( l q" G4 I' k2 Y+ Z) l( v
}) M5 n$ O7 f0 j& ]
MSG msg;
' m |- }) D" ` while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )# x$ r: C& c- {! n
{( R7 _! m: `' V, h. h j* O* T$ I' j ] |
TranslateMessage( &msg );
: y- Y0 y/ L; w2 | DispatchMessage( &msg );
( ? R( z) h8 `3 x$ q% l+ g }- ?" V o8 p8 z' b
return m_bAsyncFindRunning;
$ Q7 `1 U- j4 r9 y9 M }! d8 e# D& p1 m9 z* K4 Z1 z
$ k" X* p4 S$ p' H
* b. E0 h8 F. ~4 a5 x
TRISTATE m_bUPnPDeviceConnected;) Q- s2 V! l9 n/ q* v0 z
6 w4 s! b: q/ h4 `) |2 _4 [( k. B) Q, ~
// Implementation
' J8 a' U" e) `+ ?: F0 S // API functions+ O' A; A V0 m/ C. C* b$ V
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);9 w" I% e" H0 M9 Q. Z' b
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
. a5 y5 N% l* I: F9 D$ L BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);* W$ R1 j- u- u5 l% B- X" X
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);( d6 p+ ]' P/ n! @3 I
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);+ f( U% Q$ p @- V# Q" Y1 [' g9 \" I! ?
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
- K* v& t- `+ y R3 l% g; v4 o+ f, d& R/ u# V
|$ Y W r( P" l; c: U7 Y. W( n
TGetBestInterface m_pfGetBestInterface;* Z/ U. Y- [7 W Z/ F& O( z8 \
TGetIpAddrTable m_pfGetIpAddrTable;& W* L Q) H+ X8 v) R2 j) N
TGetIfEntry m_pfGetIfEntry;4 b. G( q! h2 Q4 j: j) `' l) v2 F; S
* i7 Z1 }2 k) V( U) [: ~( J4 o8 N P7 _, D
static FinderPointer CreateFinderInstance(); z* Y# K+ S& n; s7 d
struct FindDevice : std::unary_function< DevicePointer, bool >3 ]( B+ d7 G# V$ R9 R. e) {+ [" C
{% ?" W* d7 Q8 w! I- q$ t
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
3 H0 p0 Z2 i" s5 N9 h+ d result_type operator()(argument_type device) const
' f7 r+ S4 j3 u# L, x: _4 m+ ~! w. G8 Z {8 d# @2 Q4 q) o5 j3 b, D
CComBSTR deviceName;1 `5 T% D9 A1 \+ D1 W* B
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
$ I% {, A2 x* A
2 H/ m: }" ~( B; k( O" S! k% a0 o9 U
if ( FAILED( hr ) )
% w+ V C/ ?5 A. i/ l return UPnPMessage( hr ), false;2 n( }, Y" d" u0 D- M
9 w( c8 G% ?, t2 B% A/ D" K3 d
, O! _) S" h% C) N3 G- H% {
return wcscmp( deviceName.m_str, m_udn ) == 0;
) e6 Y5 x$ v2 }+ `) D& U5 r6 i, f; s }7 x/ N1 a' P% X, O+ ]6 Y
CComBSTR m_udn;
% c- g @7 B* u' P7 b };" v; q4 A3 |4 B* | g* N* D
5 |' q, }9 `: J void ProcessAsyncFind(CComBSTR bsSearchType);
O% E6 {: L3 k- Q" b" S" ~" ^ HRESULT GetDeviceServices(DevicePointer pDevice);
- e2 _: z- y5 n5 u* o void StartPortMapping();
# m' t7 O) h! G$ v9 x HRESULT MapPort(const ServicePointer& service);
% z; c8 c: \* | void DeleteExistingPortMappings(ServicePointer pService);# g& I% o! t7 v0 T f' ]8 x# I
void CreatePortMappings(ServicePointer pService);, f9 n% I( j# _7 v6 c
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems); E; H, o4 i6 s- d
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
9 D1 I3 w: F- c) N$ U& A LPCTSTR pszInArgString, CString& strResult);) A7 W% V% j7 J6 } `) x
void StopUPnPService();3 Z1 g, A& ~( U+ u4 K$ ^; V: |
$ o3 S6 @3 ^5 r( H; j7 P/ E3 O. U5 v* E
// Utility functions
7 K' [+ r( Q# ~4 Q8 Q' e6 R# s HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);# S& [/ ^0 q6 ~, ^" {; Q; |6 W; K# ]
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
6 c6 Z( N& U5 Y* e INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
0 {" |% e! x- p1 K1 J3 { void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
9 p1 q6 x' c Z HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
- K/ y* d! k- H$ A m! _ HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
4 p! @ j4 @ v: q3 [* o CString GetLocalRoutableIP(ServicePointer pService);
! a3 B {7 [5 r8 H! E6 }& d7 R: m- ^% m( h9 J0 S5 E
6 _& o/ ~4 d: Y; b
// Private members. |# V+ ^. J: \( N
private:
" Y. {& `% W! j8 ~: ]/ M" r3 w DWORD m_tLastEvent; // When the last event was received?2 [ g1 K9 J- t( C u: n* ~; }
std::vector< DevicePointer > m_pDevices;3 F Y" o. @/ c0 s& K: T+ G" K& F
std::vector< ServicePointer > m_pServices;
q1 J" _: G$ H' k8 M& z& X+ d9 V$ E FinderPointer m_pDeviceFinder; S3 F5 w' a0 h2 ?0 j
DeviceFinderCallback m_pDeviceFinderCallback;% z; Z5 `# C1 K5 Y/ H' `
ServiceCallback m_pServiceCallback;- w- N5 b9 x9 ^9 q1 f
0 P3 j! C- s0 `
/ d2 w, [# B4 |3 n, w6 L% }
LONG m_nAsyncFindHandle;( p2 W4 B; I5 q: l4 \$ g. a# L
bool m_bCOM;/ X+ j, x! l) W- W% U4 J
bool m_bPortIsFree;
; V; I- T- u( y( G" ? CString m_sLocalIP;
9 C0 i0 ` |8 M6 v5 t CString m_sExternalIP;2 l$ \6 G, q0 l6 ~4 G3 J
bool m_bADSL; // Is the device ADSL?& ^* M4 R3 w2 m, K3 U* O
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
' I5 O( q" D; g6 G. s bool m_bInited;: w w1 U- i) v- a& g
bool m_bAsyncFindRunning;
/ g3 H Y3 P3 F7 \9 S4 Y HMODULE m_hADVAPI32_DLL;
6 l/ J `1 M4 P8 [; O: E0 ~; P0 J HMODULE m_hIPHLPAPI_DLL;& Y) l8 G/ H" O+ o* s: ?
bool m_bSecondTry;
6 q$ P; g: ?! B6 l5 d; _ bool m_bServiceStartedByEmule;
/ @2 F2 R& N- T2 t w bool m_bDisableWANIPSetup;
( m+ j# y( d6 ?( M$ c. b0 ~" Z bool m_bDisableWANPPPSetup;
5 W1 T8 C0 b( F& }; F
* y; T7 x3 d b: p; z" {: P* a# ?
R4 Z( @0 z9 J" a% a7 x};
' N8 L: B7 v, n' g* _3 A+ X" u2 a( F0 [' J( u$ ~
7 s% e$ K3 k6 y3 V
// DeviceFinder Callback
7 I6 \5 {1 b( a2 E' ~( zclass CDeviceFinderCallback1 o" Y! g; g7 Y4 ?7 D
: public IUPnPDeviceFinderCallback
% E" x6 T: ^( W4 a+ }2 n E% S{- q6 @- ~& p" G" ?" u
public:
+ l/ j4 p, }$ g; N# O6 U CDeviceFinderCallback(CUPnPImplWinServ& instance)5 t% S3 ?. w6 N( f$ e8 a: }
: m_instance( instance )
# j, M0 E; c* W2 l: d; Y { m_lRefCount = 0; }
+ t7 W/ h8 ~1 ~7 [% j; s$ E" I! ^3 s* J7 X1 C
\9 E2 z3 z. ]2 q STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
3 `+ R/ N5 A4 [8 j" W3 M& g STDMETHODIMP_(ULONG) AddRef();4 O( N' f) @$ v/ T8 i* q) k3 d
STDMETHODIMP_(ULONG) Release();
4 ?* p' |# n* _4 [2 L* _# Z+ w7 j8 R+ g9 t4 @# ]3 K* m: t
1 S9 S2 [1 n& ]4 {( d" }8 T# p$ x
// implementation, e) p/ I( }& |9 `" q0 i
private:# P: O) p i+ ]- y9 O! N
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);& ]9 E! O9 i' C" ^# j
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
7 h8 n& B* U3 ]# f4 z HRESULT __stdcall SearchComplete(LONG nFindData); O4 s0 o& ?6 g" _: C( @
) e; p' r0 w4 \: m9 U! n; }
, G/ N' N& ^0 z9 ~1 Vprivate:
' C" f- b/ Z+ k& {. C2 ~# l. b CUPnPImplWinServ& m_instance;* a+ z4 ?+ l% k( y
LONG m_lRefCount;
* W- v9 F9 t, c; J. Y8 I}; I( m+ m8 k( s4 G3 u
8 J( h( b5 W# X _# B6 @# V$ ^. g4 k8 f m4 }
// Service Callback
7 Y3 X4 E$ }1 K. b% o% m9 gclass CServiceCallback
3 U+ Y5 T0 y1 w : public IUPnPServiceCallback! [5 P% J j: S+ r& o9 H9 b7 e
{. ~: z1 W+ O2 P3 f/ K* n
public:( X3 _. Q& n% I6 c/ b$ c
CServiceCallback(CUPnPImplWinServ& instance)7 B$ B2 o0 k4 R7 X
: m_instance( instance )2 ]. I7 R" u2 I$ X9 ~
{ m_lRefCount = 0; }' P+ H0 j1 d! R; P) g, c
* Y9 q3 ~# o0 Y" X: U
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
& q+ F) x* h9 A% x& I/ o STDMETHODIMP_(ULONG) AddRef();9 ^+ y4 {, V* {4 W: U/ [/ P8 n
STDMETHODIMP_(ULONG) Release();
$ h' D7 D0 A( r0 v* v6 [
% T" ]2 P/ r r1 P" C; V3 d: _6 Z6 p* ^$ y/ R6 V
// implementation
: P) U) H g9 m/ R0 p$ r* s ?" Xprivate:
! O2 |* l. z G3 L/ g HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
% ]; x" r, _# b' u: [ HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);# S$ a5 X) I4 ?, U& E2 Y
6 q6 D. k2 _. A8 i" Q3 i$ c4 k( O) Z. A# H% X
private:- F0 y& y# p3 I/ r9 u
CUPnPImplWinServ& m_instance;
& g) N1 H! d0 }+ g+ ^ LONG m_lRefCount;4 ]: c+ J1 s. J* l4 C0 R
};
. r1 P8 m0 _: K* h. m, }( F; p+ F& i' H0 M
5 @0 C& m0 v+ V7 r6 l
/////////////////////////////////////////////////
* F' W! _$ z( f2 t
8 N! {5 [9 C2 i, q+ W7 ], y. F- ]2 j v5 W7 h8 I
使用时只需要使用抽象类的接口。
* p k. {. `" C1 e7 `$ LCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
) r7 o' l4 m2 G) L( w, _' m5 bCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
v4 D8 x ~1 d5 i, uCUPnPImpl::StopAsyncFind停止设备查找.
+ v% h% M5 j6 O, XCUPnPImpl::DeletePorts删除端口映射. |
|