|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
9 ~/ |9 Z2 ]* C% U/ m: Q5 i; X3 |
1 `+ z+ f! W; S: L$ I
9 M+ t8 n( t" z% U! H/ G9 _///////////////////////////////////////////
9 `" I, e# \( d& `9 l2 W//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
, a% w |; |$ z/ e S7 ]. G$ l5 O5 ]" [) Q
, `+ L" `4 U* B" s2 E1 I#pragma once
& N) }1 [* C9 h; j! X5 C# e#include <exception>
1 ?5 K' X1 a( G F" z4 I3 S5 a( F4 j+ I, V+ t0 p
- R$ [0 y, c1 @: a d. l
enum TRISTATE{' Y7 s$ X9 }2 q9 H3 L2 u" \1 z9 D; r
TRIS_FALSE,8 S$ c: [! \. {: g$ J# }1 Q& R
TRIS_UNKNOWN,
2 E# A" P/ g- ^' N) C7 S TRIS_TRUE
- J$ L5 Q8 h3 \! I; D: e};- D) v! _# V9 a% u7 F
* a: g0 J2 c/ F1 Z2 _5 t' _3 F2 ]6 F
enum UPNP_IMPLEMENTATION{; {" d" M8 h+ M# A
UPNP_IMPL_WINDOWSERVICE = 0,
- s( n1 {0 p1 j, J, Q UPNP_IMPL_MINIUPNPLIB,$ |; ?- W& ~! I4 K8 X4 i
UPNP_IMPL_NONE /*last*/5 h: y0 J/ I6 j2 ~! c8 E
};
+ N3 x+ k) e1 n; M0 ^9 X" _+ m: y$ Y9 e v* v
% g% `( n. z9 B/ y' u: Q' r
- O& `2 ]# ^4 f9 K
* @. J; @0 o8 C/ c8 A6 |
class CUPnPImpl
$ [/ Q& ?& A+ Y0 T* |) }2 P& ~- j{+ h5 M1 n4 s7 s6 e% C
public:' ?) A3 y& x! ~& M( d' _
CUPnPImpl();- \3 J9 Q$ S) K1 S9 S3 y
virtual ~CUPnPImpl();9 s5 n1 y8 g3 S' U, I
struct UPnPError : std::exception {};" s! g% a T6 S/ ]& b3 |7 T
enum { Y2 }* P( Y8 B5 B7 c/ h, ]. D
UPNP_OK,
+ t& }. H6 @7 e" J! a UPNP_FAILED,
/ ]$ E) Q7 B1 k% m4 V# N UPNP_TIMEOUT
4 N. y" {" ]; f s7 J };
: }9 Z# o- v/ c0 o9 C; Q+ G" ?
1 O8 p( M6 B) R" ^) V: ]- T. c3 S
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
6 O3 ?$ i h0 B9 x virtual bool CheckAndRefresh() = 0;2 J9 E6 z5 y. ?9 b& M8 }# |
virtual void StopAsyncFind() = 0;
0 m/ a/ A3 p. f virtual void DeletePorts() = 0;
" _$ R- i. ]6 J) g virtual bool IsReady() = 0;+ D) ]- \9 {' ~+ F
virtual int GetImplementationID() = 0;8 K" {7 F# L: m: Y0 I: a% N
$ g* e+ A6 s. K/ o# n! l1 F! y
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping# H0 `5 ~, x0 y7 z$ ^% |
# ]# _8 K7 k5 A4 J" X
8 e9 k d- h# `0 p- k( m+ |# S( _; m void SetMessageOnResult(HWND hWindow, UINT nMessageID);6 Y1 t# U: V/ ^% D# y
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }' n2 J. v! S3 S9 O' ]3 \+ w
uint16 GetUsedTCPPort() { return m_nTCPPort; }
% y8 g$ J3 [! f6 x% B+ i$ F) w; Q ?1 k uint16 GetUsedUDPPort() { return m_nUDPPort; }
( F. E, K% b: }0 B/ F+ @. g
5 Q$ p0 k3 N7 f- I( K! R' |# S; Y# d; x) N! D
// Implementation X: c* ]4 D( v; I/ x: D. o6 t
protected:1 r' D- v" A# T' P& R( K. H9 y
volatile TRISTATE m_bUPnPPortsForwarded;
$ v3 B. z) ?$ n3 \0 @& {2 R void SendResultMessage();
M9 x% n/ ~1 t# r* G! f. r uint16 m_nUDPPort;4 J$ T$ D' j( L' V. m
uint16 m_nTCPPort;9 }3 j- t$ a, G8 \! q$ z# l
uint16 m_nTCPWebPort;
/ z' M# g6 H: [0 ]2 B bool m_bCheckAndRefresh;1 J' J5 H& c. H
3 ]1 f4 q5 X2 A2 m! M/ Y! _5 U
% _2 X: W, { u; L: A* kprivate:
e2 y- h; d8 {: s HWND m_hResultMessageWindow;, y9 n! [1 D S# Q: R9 T
UINT m_nResultMessageID;% H6 \6 s/ j% S$ s/ V7 u# Z4 p# n
7 x9 }. [0 {. K+ `! U& k0 N
9 b- G( H, ]/ E- m* p5 P};
, [3 E% ]$ w% [! Q' a1 A( u, D/ A4 N
( V/ l, |" F/ J' C: x- `// Dummy Implementation to be used when no other implementation is available
- g$ f+ }' f' }/ \$ g8 E1 w; V( _class CUPnPImplNone: public CUPnPImpl
, y) ?& b* c2 f# S+ D! `{
U9 D8 U2 t1 P% e4 L) U$ _# ppublic:$ U+ h* i5 N8 j- N( @9 {! h6 X( D8 y
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
0 x& d+ ^1 Z, ] virtual bool CheckAndRefresh() { return false; }3 E1 T2 A% {3 z& b$ S+ n9 \
virtual void StopAsyncFind() { }4 u' a! i* @$ D9 w" K, \
virtual void DeletePorts() { }/ N" t" a1 h l! B& ~6 I7 t
virtual bool IsReady() { return false; }
& Y0 O; r$ }& D- |/ a. N& l virtual int GetImplementationID() { return UPNP_IMPL_NONE; }- I2 `& t; }, Q$ `& a# ]
};9 D3 i# \) p: c+ s9 h2 D
3 A$ u3 L9 |/ J4 _( B8 @# j* B2 e
0 W6 \% T1 q c8 ?6 r( s
/////////////////////////////////////
. A2 S+ r- y* O5 b- J& ^1 Y, H//下面是使用windows操作系统自带的UPNP功能的子类- p6 {6 P/ }; A! a3 q- F" @& ]
8 c1 ]7 I( q/ W S8 Q$ W6 ^0 n6 i
+ \) w" w/ o) e2 g; r& e#pragma once6 V& t2 h$ w1 O6 o6 l2 N
#pragma warning( disable: 4355 )- d6 c3 g P9 W8 F8 c
+ y: {/ U. \9 W" y- \ M0 t. i/ Y: \, |+ J
#include "UPnPImpl.h"
P( Q& X/ E3 ^6 ] v- f0 f3 X#include <upnp.h>) P& ^: Y! _4 m3 G# q! L
#include <iphlpapi.h>0 D9 n+ c: d: W$ _" x
#include <comdef.h>) ]1 k" P6 _7 S/ H! l2 v0 O! t
#include <winsvc.h>
$ k* f3 i# u; Q; ~* t
+ D& n! t+ L" d3 r6 ?
, X% y' u. \; V$ Q9 e#include <vector>
: O# N4 |( F* F) g3 Z+ G#include <exception>
4 s& o2 q1 n0 }7 J; q#include <functional>
/ C$ @* r4 a, f/ C! |! e9 p
" P4 k3 d K" v# k3 o4 t7 y
9 D0 ?9 W2 \0 I2 R; X8 D6 h
% J* Y* c. R' g' [& r! i0 E2 y7 W- S) o- f, w: p
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer; z+ a3 g; J1 n- {: p! F
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
: ^) \ x& d* {typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
/ M M% Y z/ n4 ~7 L* w7 Vtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
1 c. E0 i1 {7 C. {typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback; T, s' z8 l6 N( s0 V" N
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
0 |' L9 d, U3 r0 ^# P8 l$ ntypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
; x7 g$ s2 {8 p) L3 F+ d& D2 h& {
1 ^2 N6 d% ?1 ~5 P
# g1 E4 B# c# d- Ktypedef DWORD (WINAPI* TGetBestInterface) (7 ]8 R' T' P+ D7 g
IPAddr dwDestAddr,, A' I7 G6 U' z4 G7 s3 d
PDWORD pdwBestIfIndex
) F1 n9 `% I/ q1 O( B);
) K9 I: q1 \# E+ O+ N! Q
$ |/ x6 v% Q6 c ^& s& E8 Q+ m+ P* `$ x" ?) f% H( P# t# h7 h
typedef DWORD (WINAPI* TGetIpAddrTable) ( }& P% S$ b- w1 O; Q5 `7 N4 ^- n
PMIB_IPADDRTABLE pIpAddrTable,
& i) L! o8 b6 ~. J/ E PULONG pdwSize, y8 ^ s3 F: ~
BOOL bOrder
: G c' w. N+ p# Q: `);
/ g3 U( e, w' u8 y: `
" F# P8 M. k( \$ m5 _$ J. q( ?" v/ Z# ` z# s
typedef DWORD (WINAPI* TGetIfEntry) (( x. I3 l3 c! f5 ?% h9 {
PMIB_IFROW pIfRow- }% ]$ G$ W: l# ?. _* r
);
8 O( T N `. B* n6 E) i
! K, H/ A) `9 D* [9 d1 l& R' E- C4 N7 d! v" I, g& `+ a
CString translateUPnPResult(HRESULT hr);
2 W4 T' T; @3 P& vHRESULT UPnPMessage(HRESULT hr);
/ H; A# ?+ V, i
' I9 x( _% X3 N& D5 U8 C# C# b; j* E$ K
class CUPnPImplWinServ: public CUPnPImpl
: D u& n; ^4 W0 k{( R/ d. M8 w6 P9 `
friend class CDeviceFinderCallback;5 t: Y& j; o1 C- A8 `: I. G8 o( f
friend class CServiceCallback;
; B/ w r& A. d' S% R// Construction% }& l, }8 {+ ^# s; ?& Z
public:0 q. l g9 M4 L) h
virtual ~CUPnPImplWinServ();2 K! j4 X" m- l. w3 f0 |
CUPnPImplWinServ();
8 G3 [; C7 S8 L* R+ v0 J2 _6 \$ T& b- A. I( \: d
: z B4 l8 W; C' Y) U. ~0 X; z virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }, H/ w3 `, b+ E2 D& W4 ]! s i
virtual void StopAsyncFind();
- t/ S/ W M2 l* ]% V+ Z virtual void DeletePorts();
/ Z+ P6 K! v5 x7 J3 L. V; ^ virtual bool IsReady();+ l2 n" m C: V: ^( q
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
; _, `4 D. R& o+ M
8 s& a( m1 w8 _
2 Q& F" F1 l' o" S7 T // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
* a7 U `1 D7 B# l. k- X8 g/ J2 k2 x // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later' n( {- l! s: N' F! x k6 U% U( `
virtual bool CheckAndRefresh() { return false; };
9 S0 ]0 r8 k/ r. Z, o( u9 U
. g/ Z8 W. H' [8 L
( [9 x/ X" U$ [4 ^9 k7 @7 |/ q( y7 Fprotected:
" {) g, L4 E% a5 `( o void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
( K5 e" q; A& J% x6 P6 w; n" W void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
( d2 g& P2 s: Q9 |) g- g void RemoveDevice(CComBSTR bsUDN);& G" ^. v1 g4 }* s; p, N. N6 Y" Q
bool OnSearchComplete();
0 L7 B8 |* a! a void Init();
# h, [5 V+ M$ M4 ?9 X; L) F
4 D$ G& u; r+ L5 q( q5 R8 `# y+ p
inline bool IsAsyncFindRunning() 2 o; ?6 @) T# j
{- R4 a. V+ w8 D! _! f- ^) e" f
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
# [, \ b+ M! l5 B+ ~ {
2 {9 k& G& B+ t" k0 N m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
1 O' y$ t' M3 d3 f8 l m_bAsyncFindRunning = false;1 j) k) O5 x* K
}
" K' f ?$ U0 b2 g* ?+ [) V5 A MSG msg;; t* Z' r/ n' C+ A, }
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
4 p. H5 o4 {7 t& N U" q! j {
! q4 N9 c7 n h TranslateMessage( &msg );
" O2 Q' j6 b& t( A* |9 n/ { DispatchMessage( &msg );$ l w. j# \% L0 C, H& y% B- G
}
( G x9 B$ A2 J( M/ D, D6 S. g return m_bAsyncFindRunning;
4 B9 F2 i' D# X& u }
6 h+ Z; K3 ^( O# T# x0 q1 ]. u2 M$ {( L R
/ U( {" C$ W- T1 [3 d TRISTATE m_bUPnPDeviceConnected;
! Q! S3 @& F4 E
4 M, j$ S$ A/ h' y; O- P# J% n) g M" K1 n# v
// Implementation* ^/ d, N0 Y6 t# Y
// API functions# ]( w- V* @! m u2 y: o% c k
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
6 [2 E! h" t V. N SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
f: m9 C9 A, S BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);' W% {( Z0 M: b( X5 F- Q2 I" t
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
" p9 i" L, ~2 {/ g1 Z7 d BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);5 W% J8 G$ j' O
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);5 _6 `& A) d$ a/ }* I
# Q5 a' F) u* s/ l1 f; f% K% R$ V% p
& s0 `7 U( ~! j TGetBestInterface m_pfGetBestInterface;
+ R. @3 p" `4 N( B- { TGetIpAddrTable m_pfGetIpAddrTable;) }4 e/ U, v- H3 V$ f- k
TGetIfEntry m_pfGetIfEntry;! T; Z( n" r, D4 M: ^
, }# g# k* |9 b0 l! ~7 q; s6 B3 m6 r7 A
static FinderPointer CreateFinderInstance();/ u, _- s$ M% Y: M- |# L% h
struct FindDevice : std::unary_function< DevicePointer, bool >
+ U7 f/ C5 ~, w- F- X! }( C {
3 q$ W5 h/ Q, Y& A! C FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
5 N) F% c: l, q9 P result_type operator()(argument_type device) const9 r& k% z! q2 g$ {8 g
{/ O2 `9 A$ f t: _& @
CComBSTR deviceName;
) u2 _: K/ ^0 i8 f: Z6 y HRESULT hr = device->get_UniqueDeviceName( &deviceName );
% U: F+ @" |. h; d+ _. }
, s8 ?9 O) I4 J3 R# {2 a$ P/ }
4 S4 a" z0 x3 F if ( FAILED( hr ) ). |+ u' l7 A# R% L ^ I: @4 Z' |
return UPnPMessage( hr ), false;
3 h3 s$ f/ [) ~, H' n0 ?
7 T, f8 F0 n0 W2 i0 H% A& s7 u: V7 `9 E( o5 b
return wcscmp( deviceName.m_str, m_udn ) == 0;
3 V3 e: X, r4 a }
" m8 b# n4 \+ a+ o2 H, X CComBSTR m_udn;5 E: t! O/ q2 |6 e
};1 `' @: f! }* @4 i: ], r9 E
* I E2 q" ]0 a' a void ProcessAsyncFind(CComBSTR bsSearchType);
5 @ Q) k6 C, a. ]) B$ q HRESULT GetDeviceServices(DevicePointer pDevice);( s6 @) @" ?# Q* I
void StartPortMapping();
4 |( y7 d3 Y3 C5 r# f- C HRESULT MapPort(const ServicePointer& service);6 \( ?( {9 X& b9 a3 J' k, K
void DeleteExistingPortMappings(ServicePointer pService);8 x$ M9 A9 @* F/ z: k: T% f! i) r" L
void CreatePortMappings(ServicePointer pService);+ D& N' A! O1 Q! J* H% U
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
* G- f. s5 k9 X7 S3 d& T HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
. V4 G- t" m: I$ f LPCTSTR pszInArgString, CString& strResult);" P2 R2 d. a0 v8 e
void StopUPnPService();) m0 f, L4 `* C
4 [# e: x/ O0 G& t8 P1 G7 |
% ?) E5 d0 Z' q
// Utility functions! k' i5 S$ L9 l; m
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
O x' u* `, a" N7 G# B# C INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars); Q g7 @' A8 N8 U# o: r- }' h
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);/ v6 t7 X" I o% T
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);2 z4 N! J' o" |+ a
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);$ _, F0 Z9 d0 [3 L" L
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
/ x7 g9 T: o6 O( b CString GetLocalRoutableIP(ServicePointer pService);1 _$ z& f$ y( h
* v* s( o3 i& e& j. d3 l2 h
2 F6 x+ t) }% v
// Private members! H! ]$ o& O) m2 Z: ?( |0 m- F
private:8 [# O/ E% h- ]1 X3 F2 @( e" n ` Q
DWORD m_tLastEvent; // When the last event was received?! j) N$ T+ P j. s* { @
std::vector< DevicePointer > m_pDevices;
$ i0 C) X# w) g4 S4 M std::vector< ServicePointer > m_pServices;, w* K. n4 a+ x5 ]+ P# W* q4 T
FinderPointer m_pDeviceFinder;
3 [) X5 P: [) I7 h DeviceFinderCallback m_pDeviceFinderCallback;* f+ B, Q- Y6 \& z o2 q
ServiceCallback m_pServiceCallback;
+ w( [4 L7 o4 l8 ~1 T* j: a5 V& q2 P% w
% k1 {7 f" r% `6 ?, |; t LONG m_nAsyncFindHandle;
* \) v7 r" D$ c& @" I3 a bool m_bCOM; f( Y; D" ]) R {
bool m_bPortIsFree;
5 }" S8 J9 w9 h. ^( _4 Q/ X CString m_sLocalIP;, I" F! q( M Q( Q% Y
CString m_sExternalIP;
7 o0 a6 a' @# b+ R7 T7 G bool m_bADSL; // Is the device ADSL?5 y' e ^8 k- L5 e
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?9 e3 Z# E* Z8 y
bool m_bInited;
9 ^ y1 F! R, Z/ _0 B, K; X3 b bool m_bAsyncFindRunning;
; r7 W2 A& M. B+ }: Q$ M4 O" h HMODULE m_hADVAPI32_DLL;, r7 o2 e" @6 ~
HMODULE m_hIPHLPAPI_DLL;; i+ Q# r, c* e- [0 K0 @. Y$ t
bool m_bSecondTry;
5 } @# ^) Y h: o B p$ q bool m_bServiceStartedByEmule;
3 u- R8 A; _: [. K5 Q2 `% R" @ bool m_bDisableWANIPSetup;9 d) }( ?+ e( J) A
bool m_bDisableWANPPPSetup;4 T# B B# d) N3 U8 |
Q& h, i# b) D6 n, p! m% [- j8 \3 V$ Y5 R$ _ `7 K
};' a( H% j; R: O! P2 K ]* m1 l2 n$ h
4 K: \, i+ ~7 q l0 S- A5 r$ i" |9 ^ A! ~3 G, J, D: g
// DeviceFinder Callback
/ |9 y0 B- I0 E/ x& Wclass CDeviceFinderCallback4 C6 V, |% z0 R( @) ]6 \+ p! H8 `
: public IUPnPDeviceFinderCallback
" Q" P6 ]9 Q: G* \7 r" Y{
+ d& ]5 F4 ^3 V8 ?, a2 g! y: Epublic:# X4 x, O, A$ T' [
CDeviceFinderCallback(CUPnPImplWinServ& instance)* R7 J! L2 I$ j3 B5 M) l+ e
: m_instance( instance )
0 l2 X5 w* G1 ?* T+ [. s3 e6 ? { m_lRefCount = 0; }
/ v! g+ y" ?$ X! Y" U( H: r4 a9 z: y- s( }
, g1 h& I) \0 M# w5 e7 s
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);7 X! V" i* f0 X6 w. i" d4 g
STDMETHODIMP_(ULONG) AddRef();$ d3 w) z) Z- c1 B
STDMETHODIMP_(ULONG) Release();
# J: H8 U7 ^& n6 s8 i' L1 c" b1 G& c7 k
6 O1 |5 e _7 U5 n" L( y& b3 P
// implementation
" n! Y% W3 p' ~" Dprivate:
! k6 y) r4 W s2 E5 f3 }( r HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);! j" k' [; A7 _
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);5 t' c/ I2 y4 i( T" X
HRESULT __stdcall SearchComplete(LONG nFindData);
" V& k- e8 o# E" A% b! y0 K2 Q
5 f2 V, j: @2 {* F; l N- R0 @# @4 h+ E& _* E
private:: G/ ^$ \0 E/ j# M
CUPnPImplWinServ& m_instance;
7 N% ]- B: x$ N( B* U LONG m_lRefCount;( C1 U8 y% w* s* u3 q! v- M
};
2 N* n4 U- y# `
5 F4 N# \! {6 L+ D/ P
. b1 O9 p& d/ a! g// Service Callback % v. q+ J: F) Q
class CServiceCallback$ s$ P/ p* ?+ z( d/ P9 K
: public IUPnPServiceCallback0 \. f% Z u! S' O7 D7 i
{
2 |% S1 s2 B5 Q( n6 n9 mpublic:
8 Y$ @; G! z9 a* ] CServiceCallback(CUPnPImplWinServ& instance) ^( A& F& p v/ J6 C! U9 c# F; F m
: m_instance( instance )
. X4 b3 B6 I( r, ~ { m_lRefCount = 0; }
" ]) u2 n" g; c2 r1 i2 V $ x( R8 I' Z+ A- a
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);+ u: s( f3 ?$ k4 \4 |8 y* J' I
STDMETHODIMP_(ULONG) AddRef();
. J/ M! ^' f, D0 ~. k STDMETHODIMP_(ULONG) Release();3 [9 S" M$ ^& @. a: |
: c8 o' E0 W% k7 x# t" ?, E* a+ H) o( y" Z: z
// implementation
3 b- `/ S6 G/ l2 W, kprivate:
j3 x( I( e4 i* i! X0 ~ HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
0 _' O, o2 ^! w HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
: P% E" Z9 I0 |; K* y% }' Z) W4 a$ m( L* e) I9 |6 ?: G6 Q: _: i& e
2 T, N0 |2 [* wprivate: Y' g j" R) g- d, i l
CUPnPImplWinServ& m_instance;! Z: m, @$ p0 g1 D9 G
LONG m_lRefCount;7 E& v: f+ T- }& V) {& x. g( e3 N- R
};
' c/ ]5 [7 Y! I. B! B4 ^7 Y
7 X) b& l, i! t5 k
) r8 m( w% u; M/////////////////////////////////////////////////
$ o0 Q$ F- r6 r2 a) L, z3 f- E/ d; c5 Z" M% @' n
* ]0 R8 c" d1 h% W8 n
使用时只需要使用抽象类的接口。/ y' j* `: Y) w+ T$ @$ U* @3 |' N
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
& |0 R& n% D. gCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
* ^- K y* o/ }9 Y6 [1 cCUPnPImpl::StopAsyncFind停止设备查找.
: S4 X" }( b! F7 r8 e( C- jCUPnPImpl::DeletePorts删除端口映射. |
|