|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,! S0 q4 Y0 Z5 S2 h3 Y/ g, W
/ I3 R& g- k; T8 b8 j
! f# B! f1 X9 \ V0 W///////////////////////////////////////////# s* K( h& c+ T
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
- [* \- s5 u% H! f0 ^! \3 y1 a8 L+ @
* @6 j5 d% U( s) }5 }
+ O* R% u: \. Z/ @* s' ]5 y' f7 |; @#pragma once2 {. M7 h9 a9 |( H1 T: e
#include <exception>
( c; U! w7 E' k) S+ ~8 j6 S6 {+ a, s, u- _( w- W
$ ^4 F: A c/ W3 B2 j( F enum TRISTATE{( Z) N+ o# O+ E: d
TRIS_FALSE,9 T4 |9 x- b- r9 `& y1 l5 l
TRIS_UNKNOWN,
3 T) @9 p( H" R' ~ TRIS_TRUE
; Q% t, U% P' E};3 Q& z" T# [1 v- y- w
( S M" T" h5 A: A- V3 }0 b# V x/ ]0 H. W
enum UPNP_IMPLEMENTATION{
1 u% g/ c4 Z) F# L UPNP_IMPL_WINDOWSERVICE = 0,: v# X1 x7 j' u! B: |% z1 B6 \
UPNP_IMPL_MINIUPNPLIB,3 E& F" c9 ?! {' G! b& z+ m
UPNP_IMPL_NONE /*last*/+ e: a" I1 U @) u a/ u# Z
};- I S6 \/ `# k& l" J
$ ?- `! n$ L3 s# ~; _: M7 @) {
, b& G% y+ r) d! o# F
& r) H; Y/ d7 L& {( m$ H* t
5 R) Z" o V: T4 n) T+ zclass CUPnPImpl0 u( X: b. O0 N. w' z' Y
{. r$ A4 p/ h- i' i+ c% p2 G
public: {7 N! Q3 r0 Y2 i) i. F. I) K) ]
CUPnPImpl();, p9 o P3 V. d! n8 z' d4 g2 F1 ^
virtual ~CUPnPImpl();- r2 v7 B- E# {. L7 a
struct UPnPError : std::exception {};8 {2 z) ?" v& f, W B1 w( t
enum {6 L7 c+ D4 @! v7 e' b! O- O0 R
UPNP_OK,
6 ~$ L. W* Q- q. ~- I UPNP_FAILED,- N. ]2 U6 b- b' J9 g& `
UPNP_TIMEOUT! }( C7 N, j! U' \
};
; L% D* {: N0 k& u& v/ V8 Q# ^5 \3 b5 o. X7 n
3 E0 @1 ], |* E2 X+ R
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;4 }( \' p; Z- @. o+ R- y
virtual bool CheckAndRefresh() = 0;
& X2 }9 V- o1 J/ @( _. ]5 O* W8 T: V virtual void StopAsyncFind() = 0;' g. z& F L4 j+ n5 N
virtual void DeletePorts() = 0;
: \ L, E; z; K ~) e virtual bool IsReady() = 0;. {. Y) v8 O8 D0 j4 w
virtual int GetImplementationID() = 0;# a7 L. j U* a$ h8 R3 X
3 Q6 N8 P9 m2 A; e6 x& X z+ u
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping8 b% E1 X" L- |9 v9 ?! q* W, i2 \" p
9 R8 Q6 C+ r# x' m+ ]" L
! H5 E) a. X# n& G9 g8 T: n N
void SetMessageOnResult(HWND hWindow, UINT nMessageID);9 _0 W/ M5 ^* [& k
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
. I& d3 N' x. P5 l+ t/ X uint16 GetUsedTCPPort() { return m_nTCPPort; }3 r& }" p; b. Q0 I' v0 |7 f
uint16 GetUsedUDPPort() { return m_nUDPPort; } " e/ N/ T, t! Q7 @2 a/ G( H
. t0 N. c$ e2 }% l* J
+ U% {; S+ m4 C// Implementation2 [: W2 T" P1 Q$ a, Y
protected:* s1 X; A; S1 I- I- }+ c/ N
volatile TRISTATE m_bUPnPPortsForwarded;6 ^* C& X/ ^0 C9 k
void SendResultMessage();
3 T0 X0 b$ U( N: L; f5 j uint16 m_nUDPPort;# Z, u' ?$ J, m- U) y( \5 e C
uint16 m_nTCPPort;
. `/ o4 J# p' g3 s uint16 m_nTCPWebPort;8 |3 d$ F8 b0 P$ x% @4 j @
bool m_bCheckAndRefresh;- c" x& G% h8 g( d
2 u" U+ h" C% n" y$ p9 N- ]. M3 r! d. _/ o$ i5 _! D, K
private:* Z, I$ p# _" Z, E/ y7 v
HWND m_hResultMessageWindow;
- w) J" ^3 l( I& S& `2 D2 A: Q2 A UINT m_nResultMessageID;
$ \8 O: \- D+ ?
* Y0 |, c; B0 |+ b- Y* D f' ]) a$ F$ C- {, p
};
5 B$ q: G6 \: F/ k& B/ Y& l0 z) I$ b
* Q) w- z. A) {: ^3 Y- h C
// Dummy Implementation to be used when no other implementation is available
( H+ j b# S7 k" c6 Y( ^( N% @/ [class CUPnPImplNone: public CUPnPImpl
& C( |( k" S: V- l w1 g9 Q9 _- k{ f$ I% _8 l+ W3 S. ^, } D3 h9 X
public:: A( m! J5 M$ p
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }& Y9 U" l" ^# \$ {
virtual bool CheckAndRefresh() { return false; }
: x8 c/ |- y3 q7 O# L# \ virtual void StopAsyncFind() { }- a- |8 p5 m2 |
virtual void DeletePorts() { }
& c; z% S# z% o virtual bool IsReady() { return false; }
5 h6 U x9 y% y% \ virtual int GetImplementationID() { return UPNP_IMPL_NONE; }7 P$ z: Z; K5 ^/ J' |! g) ?
};
7 K3 }6 V2 B |5 R" K
$ g+ i2 ^( A- d. g5 x% {/ }4 Z
9 ?( k% a- B: f! M. J- T! A/////////////////////////////////////
( j) a8 c6 n1 d9 T5 T4 y4 L3 B//下面是使用windows操作系统自带的UPNP功能的子类
6 [& k7 ~/ F; W/ J! ?( k$ L7 g% @* Q& Z0 g
+ M9 X3 L `% l+ |) A9 f#pragma once
/ q% T, F# Y2 y$ N3 \#pragma warning( disable: 4355 )
' h/ Y+ j$ A+ P! A5 Z4 v8 { ^# y0 C/ p5 s
% c; b& W/ p- c6 L$ ]#include "UPnPImpl.h"
- ~- h' ^& n& o: q( \#include <upnp.h>
D7 t* R- V$ A$ k' K& T# T#include <iphlpapi.h>, v Q) z; K9 B) b0 X
#include <comdef.h>3 |. J! E) m/ G1 B C5 Q
#include <winsvc.h>9 P0 _' O* X! o/ C7 K y, A
8 S7 Q' M' i6 I- |
( M$ P/ z3 n- ^ M3 w
#include <vector>2 x8 F. M1 \" `! ` ~3 s
#include <exception>
^, R" F3 H. X" w#include <functional># e7 a' }" t% C
2 }" M9 z7 ~) {* A! D% b
0 |% f2 I2 g$ @! e
$ B# z" u8 j7 g/ E6 O K9 ]; }- G
7 I- h5 A8 V5 b8 x$ I- qtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;, c' K6 ?6 f* G3 H# z/ Y, c
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;- M3 Y8 O% z- Z, O& t4 G
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;+ q) D8 g/ t* D
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;9 A4 V3 G( |$ \! \
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;$ O6 U" ]$ w5 f
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
; ~4 R" z; ?/ m1 D$ _& ytypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;( R+ l2 X+ ]& F1 W- G W! _, @6 C
0 G: V9 V2 \ j7 l# o" k( V4 i9 E+ f
7 Z) B" a3 `& l+ R5 j
typedef DWORD (WINAPI* TGetBestInterface) (" I1 }3 U* h1 y
IPAddr dwDestAddr,
2 d5 E: v7 @9 w PDWORD pdwBestIfIndex3 T& ?, v2 n# C/ Z' K
);
, C- K" f! d) M3 O2 N* N
/ g" ~1 F: u, [
( Q2 T& m H. J |" T. Q! ?. a& \typedef DWORD (WINAPI* TGetIpAddrTable) (, |; a. }6 C* B
PMIB_IPADDRTABLE pIpAddrTable,( t' W2 ]; [( a% o
PULONG pdwSize,# ~4 Z6 q0 |" W; J: f. F5 C$ Q; q
BOOL bOrder
$ T. ~" L5 A- b7 x9 r: z' W9 J);
$ T. f% ~6 O# D- u6 H) z* z7 A! m* k3 I6 _2 s! ~* `$ N
0 Y" m2 S- @8 R1 W/ S& Z$ itypedef DWORD (WINAPI* TGetIfEntry) (3 M: V- g& B8 ?4 p8 H: o% j, m$ w
PMIB_IFROW pIfRow/ J+ D0 _9 u8 Y2 d9 ^9 n
);' _' ~9 N5 W; r& m5 _( z/ l: V
# y. B6 \; t5 k0 v/ A) ?
, R$ A& q5 B( P* H
CString translateUPnPResult(HRESULT hr);5 G7 G* E4 i$ i1 c7 W C& G
HRESULT UPnPMessage(HRESULT hr);
0 P: _! r5 S! T1 T! p# p3 I5 c' ~9 w' E* F
: G! \: ?2 y8 ~- |; v: y
class CUPnPImplWinServ: public CUPnPImpl
& q/ h$ ]# y: \, R* x3 D{" D% f3 K9 `; X7 ]$ Y c0 K
friend class CDeviceFinderCallback;* T/ u7 q1 {- O( q; f
friend class CServiceCallback;
8 t, e3 r/ L+ ]8 y& a- S" ^// Construction
& S) Q; @. d' R5 U/ _# vpublic:
, ]+ d0 D5 l. s5 u4 n& P7 y virtual ~CUPnPImplWinServ();# d' H# k3 S2 W0 X: k
CUPnPImplWinServ();3 {3 e3 v& q3 L F( c
4 {: W8 ]$ R" \" {" s# J. p
9 Q6 T; i4 D; f6 w4 C$ D virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
# K7 _& o2 w3 @* G, M" p! t/ h virtual void StopAsyncFind();
( Z/ R- Q) \' ^/ G& t3 k3 X( Z virtual void DeletePorts();$ ?/ Q! b( f1 V3 h& p }# {2 h6 M
virtual bool IsReady();* |* \2 x* \4 h6 g
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }+ o; C7 z" N4 \; Z' o
: n3 b( e( u+ ]6 C3 Z: u
; e+ x; {% Q( ]+ `
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
% o: K# ~" \; r% _9 m; `* q! v- ~ // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later4 x0 G* X! @4 X: H/ e
virtual bool CheckAndRefresh() { return false; };6 _& s! p! `% e- r2 B( U$ V
2 }3 @; d7 t! k* c9 v* K
( o" `8 t: Z" r4 m( T9 @0 v
protected:6 `) `, {" v$ T2 j& n" ^
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
0 h! d- Y# a8 i% v- q' H4 J) i void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
0 `* b3 A, r$ q6 u7 G( q3 w5 E void RemoveDevice(CComBSTR bsUDN);
# p: o' I$ F, X6 V bool OnSearchComplete();
) {. I9 }6 M% F2 N$ J void Init();
' z7 I0 w" L! {9 c3 z, t+ {+ R# K
* z, C( F3 ]1 ~$ [5 h3 W& ~: P/ C: ~) x
% J ^$ B' e! e2 {+ j: M; u9 N1 i& [/ F inline bool IsAsyncFindRunning()
d$ i% r- A( ~ {; F _ R' _& B4 a
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ); a% t) Q! }( v
{
0 p$ ^ _0 T2 P) P3 S m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );0 @( b$ {2 i m7 F* u/ s
m_bAsyncFindRunning = false;* n8 l2 e( T; L/ h7 ^! t
}1 z, R2 b; Q+ {! B6 Y
MSG msg;: O, L6 L0 x! ^5 e4 J" ]* S$ Y1 I' R
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )8 D. G- t) z% {4 g) |
{& w1 |: w- o, X8 f
TranslateMessage( &msg );
. G; |+ R6 p; z% `# T DispatchMessage( &msg );
4 }6 t( r* B/ o$ \' W$ g }
: S* P; _: e5 l7 R return m_bAsyncFindRunning;
. z& Z5 J- r4 \- C }
+ `- L) g" n1 G4 T3 M, O0 y+ ?$ T) d) u& a& g V6 d: p3 ]: Q8 ^3 u
" }2 ]$ T' \" R% s& @+ g
TRISTATE m_bUPnPDeviceConnected;
- A7 r" K: l' d7 m3 u3 [
; B d! j6 n' K. K+ k$ ]8 k) [4 S5 a
// Implementation; b; \; C- L0 L- F- z
// API functions
* V- U- f( w' y% Y+ j SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
( t E! B2 K6 m6 N4 O+ ?- q E9 X. c5 i SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
8 U, y* f$ U4 P! g- N BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
; p5 m d$ a7 E$ M4 ~2 g BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
9 K. z$ a$ |2 n: {( g BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);3 q \! N4 E6 s& w2 y- t
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
( e; _6 h% y8 y. S. t5 O1 B4 v" Q3 e3 o
% u0 |/ d8 N5 Z K- N
TGetBestInterface m_pfGetBestInterface;/ a. f5 Z( `& U
TGetIpAddrTable m_pfGetIpAddrTable;
7 o" B) G% X* U' Q6 L TGetIfEntry m_pfGetIfEntry;# Q1 K3 U0 D# M4 O6 K
3 a2 C* N& N! k! T/ o+ ?
! P1 Q: c, f c0 S9 b! n5 l9 y static FinderPointer CreateFinderInstance();- L2 X8 V% C9 J7 ~7 M3 T
struct FindDevice : std::unary_function< DevicePointer, bool >0 D& q, f8 [6 C- r3 D# I' X
{
4 m6 u. x7 r8 q* ? FindDevice(const CComBSTR& udn) : m_udn( udn ) {}: }9 J- w% w! V! `# H: ^# P1 X3 _
result_type operator()(argument_type device) const
) N7 }4 l# O7 B" x; Y {6 R% v, z: c/ t% l* }+ J9 Q
CComBSTR deviceName;
@# A/ G" m- r) x- ]! { HRESULT hr = device->get_UniqueDeviceName( &deviceName );% n6 u9 [& X0 W; ?6 z
% v2 Z" l8 Y# {+ F$ Q5 C5 s) N! [; n/ u2 J! }+ ~' u
if ( FAILED( hr ) )* q5 W8 v" E7 i( O V. b# o
return UPnPMessage( hr ), false;
8 @. G' S2 F+ G% U, K ]
0 b8 b- ] p7 P ]( n, ? T" ?/ T2 X) h7 O
return wcscmp( deviceName.m_str, m_udn ) == 0;
/ T4 C$ W2 w1 J# f }5 M1 @* d4 C2 |2 o
CComBSTR m_udn;
' M) s* [& a' x8 m };
" K: l& y& E% d3 R* h7 p1 j
O/ i" n2 `; ]6 i void ProcessAsyncFind(CComBSTR bsSearchType);
q; h" z% E D* i; A0 R HRESULT GetDeviceServices(DevicePointer pDevice);
/ f) q2 h- C6 P5 {3 T/ I2 r void StartPortMapping(); c, B% h- @) }' B# K1 L; C$ j
HRESULT MapPort(const ServicePointer& service);
" \ |: R; y8 m5 x: P; b void DeleteExistingPortMappings(ServicePointer pService);
; h5 Q. [ {* u& J Q: \ void CreatePortMappings(ServicePointer pService);1 f. h6 e8 ^- r2 O8 G; X( [
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
# e$ d1 l. ^7 B+ W7 ^ HRESULT InvokeAction(ServicePointer pService, CComBSTR action, ) e4 Y* O0 D% e; E d2 h$ g* L
LPCTSTR pszInArgString, CString& strResult);
4 P& K& I6 \" ]- K; r% h- K$ ` void StopUPnPService();: i+ @: ]: Q4 I
# V! }& A( Q5 |3 ]! D
& J9 I3 Z3 V4 g9 \5 u) ]. J
// Utility functions, m; Z8 `- X {# B. N: h
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);( W$ N$ v( o! p+ G9 O$ f8 P
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
- n7 w0 m2 z" K: B" S$ E# w& G INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);' T! L* w. J9 _* d/ T
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
+ `/ M/ x* v- t) ?8 \7 @0 w HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
* G8 X( }* _; V% V }- M HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
: V5 e) `' j5 W5 R; \/ D# _( Q3 `( F CString GetLocalRoutableIP(ServicePointer pService);7 H8 ~3 r' F: A5 N
0 c& N: S9 a+ L1 H, ]- Z6 ^$ X* T& X$ t `! y0 J
// Private members' T* [) a+ j: w+ a' A0 `1 z
private:
0 y y# \ _0 T( n DWORD m_tLastEvent; // When the last event was received?
, |) o) ~( T) g: m. D, t std::vector< DevicePointer > m_pDevices;" d9 k4 N# ]& s g% w
std::vector< ServicePointer > m_pServices;
* m8 K% |' b) N3 \7 r) ] FinderPointer m_pDeviceFinder;
/ a- e5 L8 ~" p& V DeviceFinderCallback m_pDeviceFinderCallback;4 ~7 M+ P) r7 b; `
ServiceCallback m_pServiceCallback;2 H* k2 M! v L4 s5 J8 Y: `: w
6 a7 Q6 `/ y- W* r* T% @
' R5 `5 J( y0 Z0 z7 @& B! Z1 j! E
LONG m_nAsyncFindHandle;
t2 g9 f1 f& o+ x9 _, P; U$ m bool m_bCOM;, g. D2 ]5 t$ `
bool m_bPortIsFree;9 ? b0 f% g* ?* o0 v
CString m_sLocalIP;6 \" Y Z2 p! c6 T( }/ E
CString m_sExternalIP;
9 @7 d3 N5 W$ y, } bool m_bADSL; // Is the device ADSL?5 e# X y1 B6 F( F( @
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?4 o2 H: ]% v$ u- M
bool m_bInited;
3 {6 `1 {" M% w bool m_bAsyncFindRunning;
+ J. t2 `+ x2 A" o# ?3 L HMODULE m_hADVAPI32_DLL;
& u& @' ~* @2 l( n HMODULE m_hIPHLPAPI_DLL;4 S; g3 u" p' l/ C8 ]' V
bool m_bSecondTry;
+ v1 X( t! Z; x/ [$ Z9 h* l' @: W0 b bool m_bServiceStartedByEmule;1 P0 t8 e6 {# S$ t8 r8 Z4 q+ n
bool m_bDisableWANIPSetup;* o C' X( d$ G* ~- j* |% s0 T
bool m_bDisableWANPPPSetup;3 R7 Q. u9 Y9 i) M) J2 U
+ y9 D$ f, n' e/ r( L
3 {% m6 F9 S; e9 ~
};1 k& I* C0 Q: n2 K( N2 C+ x6 ^4 d9 d
/ ^% M' J) V4 |+ ]; |% r9 _! s: `& G! d# C
// DeviceFinder Callback
- h. H; ~5 R% gclass CDeviceFinderCallback
x% Q) U5 u2 I6 c; h: S5 q : public IUPnPDeviceFinderCallback
; V9 w1 Z, {3 ]2 e$ T3 R$ a" E{4 d9 P$ Y8 S4 t( _! e+ ~
public:
6 k* R7 J) ^" N' [- ? CDeviceFinderCallback(CUPnPImplWinServ& instance). _( w/ J+ h6 \& D- c, Q- l7 \
: m_instance( instance )
" b* G5 P5 Z( g- a { m_lRefCount = 0; }$ f$ L. g4 ]' R
# w l" z# D9 C) ?
& q% a5 c/ j* r) n STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);4 h/ y6 x- f, N% h
STDMETHODIMP_(ULONG) AddRef();
! B- V1 P/ ^6 t, V c STDMETHODIMP_(ULONG) Release();
( z6 t1 O8 i0 @% `' q% k
% r+ \/ k1 S) j& T
8 F: m/ c% k. j: b+ l ?7 C// implementation, ]4 x! k" m' k- ^# X4 p1 j7 b+ i
private:
/ n9 b' n# y9 Y6 F% F+ m HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);( U8 Z9 V' B" O, O! t
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
+ v1 F& f$ c. G7 a7 h HRESULT __stdcall SearchComplete(LONG nFindData);, R; Y ^7 t8 e) Q* M7 J5 j
4 ^ a' u7 N7 M6 g2 g7 d3 j& \. N) ~* I( m' J7 Z& j* K
private:
M% k, p% t6 b CUPnPImplWinServ& m_instance;
% v8 m; z2 a! h% | LONG m_lRefCount;) U; {$ i0 z7 B6 j, W8 z8 q5 z
}; J* q- Z" c6 g
. y; `$ W4 Y2 @
; m% D7 o6 S Q8 u) ~' Y// Service Callback
9 d7 I1 }' q }2 ?! A- g/ z* hclass CServiceCallback- m5 ?. I; K$ l& R1 a, I
: public IUPnPServiceCallback" y" X4 o1 K8 l/ j- I
{+ E! S1 I, \7 I) d2 N5 S
public:6 h) a( Q! w* i, B' G
CServiceCallback(CUPnPImplWinServ& instance)
( Q0 ~$ c8 c# M, `$ Q : m_instance( instance )
+ o$ [ |; s A# V7 E \8 X { m_lRefCount = 0; }
/ P7 J' W8 r' h1 h6 k) T
& X2 ]/ J5 s, b STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
5 ?. x3 \. W4 p# v! p STDMETHODIMP_(ULONG) AddRef();
z3 g% F* [# ]! w* a% l STDMETHODIMP_(ULONG) Release();
/ |3 w( U2 @: J7 W4 c3 R* s* e$ ]- i5 Z0 {, [' H- t
; N* B) }2 g! L M8 ?4 r
// implementation
" |1 F& g+ [ U# v; x; Qprivate:
; m4 ^8 X4 \' E; | HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);5 L8 X9 |1 H3 _6 z, E; t* e) X3 \, q
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
* u2 ?2 T) H, g/ r% g/ {8 l
8 A# b1 P' `) D5 d% t
3 g6 q; N0 a& vprivate:
$ w9 [ X/ L$ S8 j2 e CUPnPImplWinServ& m_instance;# ?; g' a. Y8 ]- X$ T: S, Q( ]7 m
LONG m_lRefCount;
$ ?/ i* C- _ ~ q};
" y6 Y* r% Y @1 i W0 z- h
* P; V0 O6 |# F/ M E4 U: B, @ _: m3 d2 ^7 P. ^1 |
/////////////////////////////////////////////////: v3 Z7 Y9 O; ?' \
' ?" R0 M. Z+ g: X( j
. n/ |+ R/ t5 y2 O) C( d a使用时只需要使用抽象类的接口。9 P ]. V6 @$ c3 d4 t9 u% _& k
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
; \3 G+ B3 W: J' ]9 d2 N8 XCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
% s3 p/ P! ?" c/ ICUPnPImpl::StopAsyncFind停止设备查找.$ r4 Y: S# H8 C) W7 ^7 v1 |
CUPnPImpl::DeletePorts删除端口映射. |
|