|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
) Z+ ^6 r! I, e% A8 L+ k) i& f+ s, z5 d1 A6 O
1 i3 v1 D/ H7 h9 L
///////////////////////////////////////////- ~& \7 |- m7 l' W$ v/ \# V) h6 l: w
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.0 g1 B }9 U' _: h( d
6 q0 U, T" y4 ]- ~1 i+ j% A$ P
4 `% ]; Z, `2 ?% w" d8 D#pragma once) |2 v, P. H# a6 d) q# s. [5 [4 o
#include <exception>" _' E3 T* R6 \2 Q
' }: |( ?/ D5 q7 B& b5 {' _/ Q8 z' z9 r1 m' i& S9 |7 S: l7 d
enum TRISTATE{
0 f# C. F# [6 k- |0 t TRIS_FALSE,
% e- d7 O2 y- G5 @% }; _2 p: p% M TRIS_UNKNOWN,7 w I' }# j) t. w
TRIS_TRUE
( g3 I- n- F: M& O9 U+ }3 h};1 ^2 m& \8 @( x2 m H
6 V! J+ w2 L9 D5 F1 [8 w6 p7 o. k: y, U* o2 X2 l. J
enum UPNP_IMPLEMENTATION{
6 y+ c/ _- m5 [4 Y0 b- `# ~9 N UPNP_IMPL_WINDOWSERVICE = 0,- k, W- ~: C1 x( V0 T
UPNP_IMPL_MINIUPNPLIB," O( I9 R9 f0 H b
UPNP_IMPL_NONE /*last*/8 d. n& A) C+ g4 Y' Q2 t
};6 O5 v j r# i+ E8 d; |+ ~' c
; _) ?2 Z3 u4 H& l# y
! e6 E; g$ y8 c9 V* v. Y# n4 v5 ^2 F5 C t$ X+ |7 F2 X
8 G- a# z8 m3 mclass CUPnPImpl
% J5 l- ]3 q8 W4 e{
1 F0 }% y( z# s: Upublic:8 u d0 N# I+ o9 k
CUPnPImpl();2 V5 d, _$ n0 l7 Z
virtual ~CUPnPImpl();! o, E3 E, Y, b3 U* J9 S
struct UPnPError : std::exception {};% K6 |6 E) @8 b+ Q2 ]* y
enum {* [5 ]' @- q; M, g- X' w
UPNP_OK,& I" M, l, K) |' d z% v' B
UPNP_FAILED,
& Z- H! b6 ]2 |5 f UPNP_TIMEOUT
0 V& Q, z3 H) r* ]4 F };
+ n: y$ I" j! {2 C; \4 Q
8 [- H( h& R i+ k/ X9 x7 @6 q+ S6 v5 R q6 s3 [9 A; u" y
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
( b7 t* Z" Q1 i# y F( |( q virtual bool CheckAndRefresh() = 0;
% D @9 q" \& H* B virtual void StopAsyncFind() = 0;
8 G7 K; {# v/ z3 s& @& n& X virtual void DeletePorts() = 0;
F+ ?8 t( Z6 | virtual bool IsReady() = 0;
* i2 H( J: O a9 H6 ]/ n virtual int GetImplementationID() = 0;8 c! L4 v+ l" r4 b* j& ~3 f
# h; u5 x$ S/ i3 G6 u
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping/ j) i' m1 k$ z
5 @/ t/ u8 {9 i, q! T- M
; j; L% ^2 {3 B/ I( B/ I
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
0 ^% [( l0 f. K8 e TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }8 y% F) d9 c: u8 ~1 G
uint16 GetUsedTCPPort() { return m_nTCPPort; }
2 V( R) i/ q6 r" g1 y uint16 GetUsedUDPPort() { return m_nUDPPort; }
' l' D6 b- C9 d/ U" H' m1 X; y
U7 Z) O* `" z/ t
; o2 @. w3 ~7 ~+ r6 S% ]// Implementation+ ^$ U5 Q8 S9 S' K* f
protected:
4 ?* a0 V. ]3 v7 P% G; K" e/ d volatile TRISTATE m_bUPnPPortsForwarded;
1 H5 D* Y+ }# }8 t- {9 b# v void SendResultMessage();5 m7 n: @7 q9 X' {- m
uint16 m_nUDPPort;
* w/ Q% l! l0 y9 c d+ h" n1 r uint16 m_nTCPPort;
' S- u7 C9 e4 Y, { w uint16 m_nTCPWebPort;& _6 `& w! f4 {/ g. j
bool m_bCheckAndRefresh;' |$ B% h7 D1 w! Q5 z9 g2 B
1 H' p! H6 E2 [
5 s: ]) m. V# O9 |9 Sprivate:
4 M1 h+ {- j- i7 u: h HWND m_hResultMessageWindow;
5 ^9 u9 w! }8 J4 n# R! O! M( e7 } UINT m_nResultMessageID;% ~$ K& C3 X1 C1 Z/ e
6 l: t4 f* e0 L
3 s: _+ F5 l$ N" @* }0 s};
7 z& w# T5 _4 L/ S% P: `
0 n+ d2 E5 I+ j2 B/ \. l* l) @0 P
2 H( A; e( c6 s3 \0 C1 X// Dummy Implementation to be used when no other implementation is available
/ E+ \$ j @3 E" v+ p! }class CUPnPImplNone: public CUPnPImpl6 Y( U8 s# b+ p& N4 K s
{1 j. C/ ]4 n# i( R
public:: [" L P5 j W" Z ^
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
. p7 y) I7 V, h2 U4 Z* @ virtual bool CheckAndRefresh() { return false; }
( V7 S4 W3 O! G) Q; ? virtual void StopAsyncFind() { }* L# C6 q4 D% s; [& h+ S
virtual void DeletePorts() { }/ n# B/ i: H9 v) d& j1 \
virtual bool IsReady() { return false; }. l' l. C) i" G1 V' Q
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }& p6 M6 ~: h4 }
};
7 ^9 _7 o. W A$ q& k8 T2 y2 v9 a a: c; O: ]0 U/ d; y
1 D i. }& R' j/////////////////////////////////////
: N5 a, k) x- B% P3 d//下面是使用windows操作系统自带的UPNP功能的子类 e9 U# O4 p7 Z) k6 c& n
$ z) G9 a; b/ G G8 x0 X4 J. z P
* m/ t( D( x' o3 I#pragma once
1 N2 `, F) u8 F& y#pragma warning( disable: 4355 )
( R: v" x* n0 e
t, c6 N& [5 W6 H. h/ ^, z3 V. r) G# M8 \
#include "UPnPImpl.h"
}. t1 A/ R7 f9 g8 s5 n) h#include <upnp.h>5 [4 ^. B/ T' m4 r2 t, ^
#include <iphlpapi.h>6 P5 h. g, k' T' `% E
#include <comdef.h>
7 I; |# R6 y: O; c' U* [#include <winsvc.h>5 n- t/ e3 H# j# T/ m* z
: t- X0 u" G6 o2 \% a
# @, r0 d1 d2 t#include <vector>
8 Q# b- e% E" m#include <exception>
|# w7 L$ o& p0 T+ h5 N' A#include <functional>
% Z- _8 c" C q0 N; |& \' K% v3 T% P. {# C9 H$ {* L, I
! v/ V: T' @" h! e
$ m' E* i2 Z1 w
- M' L6 a) m8 z2 u; l- w+ Xtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;, r P! G2 x! C9 @
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
4 O$ z% |8 ~' S$ I8 Atypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
; v3 v6 }- F7 z) ]typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;- U% k0 i% v5 j
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;: e6 m6 `+ {/ H5 R/ w) G9 ?' ^
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;4 T* j4 r( k; ^) w* Q) _( ?& e$ i
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
: u. t7 w O8 ]
! i" H+ E& [$ S2 q4 o* n- z; J( \3 {3 t
6 ^7 m+ u2 E$ Htypedef DWORD (WINAPI* TGetBestInterface) (1 C1 O. p7 A, I0 W; D2 {4 Q
IPAddr dwDestAddr,! d& d- i2 _7 l1 R" D( O% S
PDWORD pdwBestIfIndex
- N. A1 L' v4 l1 p: H$ p);9 X+ Z& z+ d- N0 [* A
% C5 E4 {# [& ]
/ U2 ?6 F: t# x5 k9 {% btypedef DWORD (WINAPI* TGetIpAddrTable) (
! x# O* }* h% r9 Y& g- t PMIB_IPADDRTABLE pIpAddrTable,
2 x8 p3 x1 z. i( S: a1 U s6 c PULONG pdwSize,
) G( R1 K& y' T$ C. \2 n# }: i% a BOOL bOrder' F: x$ P9 N9 z* \) U+ W$ j
);# \1 Z- ]9 E% F9 D; S8 `
; R: c3 r) _- u; z+ Q
2 Z2 F! X1 a$ O m5 atypedef DWORD (WINAPI* TGetIfEntry) (
1 J( O4 K- e7 s( j' L7 k4 \! G( L) @5 \ PMIB_IFROW pIfRow0 h# d9 u. z/ r' m' {0 N
);# \3 A( n9 \; J' V
/ e5 u" y6 z/ i& T, T2 f$ B
" ~% l! {0 C6 K% E% r1 ZCString translateUPnPResult(HRESULT hr);4 H4 V1 H- X, q1 m. ?+ }( j
HRESULT UPnPMessage(HRESULT hr);
& ?( W( A! o2 @4 l, h% y6 V7 V8 E; _( _
6 D) e; Y5 r/ Vclass CUPnPImplWinServ: public CUPnPImpl: Q" m& d( b- d# k0 V0 y4 C3 `
{) j3 I, ^" `( l- ~* B- O; m4 Q
friend class CDeviceFinderCallback;
3 r$ j( |1 ?7 N& d friend class CServiceCallback;$ R+ H- f) P; _8 c" {: y L
// Construction
2 `& s6 |+ I5 m! X3 Q9 k5 zpublic:
& d; ^7 x% {4 N! x6 p) n* H% ] virtual ~CUPnPImplWinServ();
3 m/ a5 T( @9 a ?/ r8 i. l CUPnPImplWinServ();& W" y; T4 }/ ~: M
7 u( }- d2 E5 \6 I* O/ ?! O( N
3 F3 t* V2 Z. R' T# m
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
0 Z4 e6 f' K: y# c virtual void StopAsyncFind();% d/ N1 |# ^5 c0 q+ \! S
virtual void DeletePorts();/ ~+ d- E3 T/ z+ ^- `
virtual bool IsReady();; W* {3 X5 Z' H+ a+ T- p
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }- }) L6 R% u$ `1 U
! H5 Y: r# G+ R% i9 d) c' f1 i
( u& u$ t) C6 z* b+ f
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
" ?0 S4 _$ W% D$ k0 u1 R // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later+ ^" C T9 O) F! \9 W
virtual bool CheckAndRefresh() { return false; };4 U& D. |+ R J: s( l4 c, r, c
' N# l+ A# b' ], i2 M( @+ J4 x7 T- n8 }" g& `
protected:
( [* C$ \" Z6 K! M2 E void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
% ^) V- g8 f# {8 h# [ void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
' `- m% y! C" I# b. f- A) p void RemoveDevice(CComBSTR bsUDN);
( Q) k4 N8 a; k+ n bool OnSearchComplete();0 w) l3 v/ k ?% Y" Q
void Init();
6 d1 W. K6 _% b- `) [! {/ L! A Y% T! [! |( j7 i
, n) X1 |( o+ O
inline bool IsAsyncFindRunning() ' J! a* _4 `: U9 O
{
: V% p8 C j: h& B if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
5 ]+ ?% h* f2 \" ~/ n" h2 l: S6 z {
6 ~' M ] A$ z6 q m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );( d; D/ X t3 I
m_bAsyncFindRunning = false;
/ X0 t* M0 N: i! w9 f) O }
4 a+ {3 w, T: _0 w T MSG msg;
m9 k* a S7 Z3 ~# ]; K- Y& B while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
1 ~: t, S& u. m, x5 U" r2 f# A6 E {
7 _& c6 C W( E, a/ t TranslateMessage( &msg );# h0 L/ X l# n# z6 u4 c
DispatchMessage( &msg );6 H% Q. @7 i8 W3 V' \& a) _3 X: b
} p% E% p7 ?- Y3 N: e) l; M& W
return m_bAsyncFindRunning;
6 r5 o3 V9 ^- o( k' S* n6 w5 U }
: {) ^/ ]+ ]$ D: o, W( {( w/ o9 ~5 i
. X. v( K5 H$ F
TRISTATE m_bUPnPDeviceConnected;% ~/ @; h3 i5 O# y+ o+ y
7 G E1 F: a' a: F7 f! E+ i7 c( \6 I* s; P
// Implementation6 s( o: l6 D6 A- a+ K
// API functions, N- i4 I$ P6 d: C; K
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);$ t( ^# f0 f1 y9 B
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
5 H7 I( G4 \1 r+ n# a3 F1 G X; H/ @ BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
( w3 b& b7 m" K BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
! O) }/ D9 d& ] C8 R4 ` BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
1 h" Q+ q* M! a6 r BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
$ z+ j1 s& ^: J8 p2 s6 }. }1 y" g1 h+ A# m1 q @
# _& V8 H$ R* m6 L TGetBestInterface m_pfGetBestInterface;$ I" I, u; Y h* V6 p8 }% k% w
TGetIpAddrTable m_pfGetIpAddrTable;4 @; } T# M$ k7 J8 G5 W! E
TGetIfEntry m_pfGetIfEntry;- X9 `: X: I4 }* C: F9 @
& \, A+ i& H3 O: y5 g# `4 u5 h. j8 r% W# p
static FinderPointer CreateFinderInstance();# ~' |$ c& |* O, _* a$ p, X" r
struct FindDevice : std::unary_function< DevicePointer, bool > R- e3 \: K/ N* [+ o: V
{
4 H1 s/ E$ e- V+ n! E( U FindDevice(const CComBSTR& udn) : m_udn( udn ) {}0 z/ ~% P+ _! g$ M7 C$ ?5 [
result_type operator()(argument_type device) const
; ^1 U# {5 D$ i+ T {
& p ]' H( m# a+ T! z5 B- U9 L CComBSTR deviceName;% ^/ {- J1 H6 T- n; N/ s! s+ A9 }9 F
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
* ~: ]1 s4 Y E+ Q" O9 x' Q. s. v6 c' C0 [& o6 ?. p
0 P/ G% ?8 `, p4 g$ ~1 S5 a4 p9 q" m
if ( FAILED( hr ) )7 L; {5 W5 w. S
return UPnPMessage( hr ), false;
5 g ]5 F9 _/ g+ s
, z% ]! u/ G+ R3 i# q4 T+ n1 a9 S# {1 l" n0 m; J0 R {1 H
return wcscmp( deviceName.m_str, m_udn ) == 0;! f0 G9 r; w0 V7 J& T0 y% h G
}
|" I1 n+ Q, w2 ?3 q% B! L CComBSTR m_udn;
, J' [3 m; T6 K };
! `) ~0 `, O" B: {, o2 f
7 n) M9 e" N' }( T6 l void ProcessAsyncFind(CComBSTR bsSearchType);3 n% O4 J% _# k9 r R6 S( Q
HRESULT GetDeviceServices(DevicePointer pDevice);
, D* C: L$ p" b void StartPortMapping();7 I0 n* ~- z7 q+ X0 y- M
HRESULT MapPort(const ServicePointer& service);8 I7 G- m' z, o: j; z1 y* ^0 N: Q
void DeleteExistingPortMappings(ServicePointer pService);7 Y8 x! T5 ?6 A6 {- H3 X, P% U# u
void CreatePortMappings(ServicePointer pService);7 }$ Q6 d; _, x+ H' A9 j
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);2 n, O9 d6 K, P( K- ^/ s( R6 B
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
3 S$ V9 `9 I6 Q( C r" r9 ` LPCTSTR pszInArgString, CString& strResult);
! c8 f& \ g( Q9 J, T2 o" w1 V5 E. Q2 u8 a void StopUPnPService();! y4 ?% a- p# n+ J/ b% o+ h
# N" |7 P" ?" A5 A/ }5 S/ d1 Y% M f+ L' R0 I+ N
// Utility functions. d' M: I5 O& |! a }8 A
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
$ e+ L* ^; r9 x& P/ ~; q& o0 a4 M INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
, d3 g( i6 j% }- O4 [1 C INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
- m s$ E. n! @) P/ h1 c void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
& u% n# s& ]/ o( [* y HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);6 z; m. A3 L4 [% Q
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);+ P7 ^) z: `- S- n; D+ x
CString GetLocalRoutableIP(ServicePointer pService);
9 \ @- E t1 q4 {2 h7 ? P7 U( H. K; y3 Z" S4 w* v/ q
: P0 N1 ?3 s2 \" m8 a// Private members" q6 c2 |; a/ _7 v3 ]
private:+ I$ C' o* O5 T, N0 a% H6 R
DWORD m_tLastEvent; // When the last event was received?
# r/ Q6 z& f2 j( F& F- E std::vector< DevicePointer > m_pDevices;
% Y) M+ K' h% T9 Z std::vector< ServicePointer > m_pServices;% a' @: K0 i% D) c8 ^! T
FinderPointer m_pDeviceFinder;/ z9 a2 {$ o$ G9 \9 k9 Z0 s0 t
DeviceFinderCallback m_pDeviceFinderCallback;
- _; [" T2 }; k% ` ServiceCallback m_pServiceCallback;$ }) }1 J( o% Y$ L
/ N a- u, ?" a, w1 u+ n
/ h6 Z5 O- Z" U$ i3 [ LONG m_nAsyncFindHandle;; ^2 x; O' b6 E9 F# J; @
bool m_bCOM;
l/ m' x( g; W3 w1 N, g' F bool m_bPortIsFree;
. I3 q' D# g. p! j2 E, X6 h CString m_sLocalIP;) _- N, u0 c# ]' m/ Q* H
CString m_sExternalIP; c* K& p7 H! g0 Y. B' J
bool m_bADSL; // Is the device ADSL?
4 V/ B3 Q( ^9 ^ bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
# `% n, E+ E1 [* S; S! W bool m_bInited;! ~$ |% z: o( H% f) d8 o- i) c
bool m_bAsyncFindRunning;, D4 Z( f# S& I* f( o B# D
HMODULE m_hADVAPI32_DLL;8 A' [9 Z5 _/ A9 A
HMODULE m_hIPHLPAPI_DLL;
' R$ k D4 c# f5 S$ | bool m_bSecondTry;, \, X7 R& D, a/ @. d
bool m_bServiceStartedByEmule;
+ y% d2 T1 e( o& { bool m_bDisableWANIPSetup;3 T5 e% Y% l) Q( Y Y
bool m_bDisableWANPPPSetup;
0 h$ W! H4 a m2 x |( }" A. Z' O8 l8 H; {& J# w
1 P" [- Q( t0 R: H* q; N
};
+ d7 _ e: L( P& Q& K, l# Z2 Y9 C" q: c' q5 f- e, a- C, m
8 Z! ^* h5 f8 E( K9 v/ P
// DeviceFinder Callback
% F0 \$ E: D' L9 w1 C! K! mclass CDeviceFinderCallback8 V6 M( |0 e, m T$ f1 V* z1 Z# C
: public IUPnPDeviceFinderCallback
* o5 B6 e/ I6 M: v{
- `0 v; ?: A; h" m7 y8 ypublic:+ s3 q4 y$ D% H0 U0 s; v6 t
CDeviceFinderCallback(CUPnPImplWinServ& instance): k8 H8 Y6 N3 g) ?3 H+ K
: m_instance( instance ). ?' y6 k4 `/ ]3 Y1 z) p2 |+ u
{ m_lRefCount = 0; }4 q" J1 g& W3 k- k
: Q8 L- z6 Q5 G0 o! C: j
1 Y. S0 r2 c+ Z
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
2 ~3 _1 S; `9 D( X; p# p STDMETHODIMP_(ULONG) AddRef();
$ M0 c1 E. I8 p' m9 f$ _ STDMETHODIMP_(ULONG) Release();
$ W$ V9 P0 t* e# s- W% K. Q+ G
4 a5 V- ]! m$ s ~; p* j- X. Z+ v
) ]* B7 j W: h8 v/ s// implementation
" _2 _. t R b7 z' ?/ q% Mprivate:
6 b4 g, C4 I7 {8 N! u3 x HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);. n! m: q; h8 c8 `
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
$ h$ `) c8 X6 z1 ^ HRESULT __stdcall SearchComplete(LONG nFindData);2 z% G8 W3 p& W/ m
$ b/ r& I) v# r& o, }9 T9 x
/ r. X' @8 u. q: B, eprivate:* d: c- O9 K' t. m# d
CUPnPImplWinServ& m_instance;0 V; a3 n4 N, `( V/ b2 w4 B) y# b
LONG m_lRefCount;
! F5 Z6 s, L- |2 Q3 I9 m};
$ H) O8 K7 y9 L' y9 O: b* N& ]+ Q9 e, s
& ^% ~6 k3 ?& Z% s, g$ ^
// Service Callback
7 A, E- v% |' J! t, w+ Xclass CServiceCallback$ @- n: R" U2 R7 p' L* ]! u0 q* f
: public IUPnPServiceCallback
5 {6 q9 H8 a- S1 O* _# F) V9 ~{ n. ^( H7 z0 `6 W3 w) y3 o5 K
public: [- D6 s* z) R3 T. |8 [6 t
CServiceCallback(CUPnPImplWinServ& instance)
& B6 B6 \! ?' Z : m_instance( instance )9 b8 f7 F: u8 @8 u- i. W
{ m_lRefCount = 0; }: b9 L) x2 R( U
/ x* [# |: ^! ]! f6 M: n l, S
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);& }1 ^; Q @2 D6 } N, G$ L; v
STDMETHODIMP_(ULONG) AddRef(); C5 R% Z0 X( ]- ~7 G
STDMETHODIMP_(ULONG) Release();
/ @2 ^) R; F6 N+ e8 I
# w, M; ~6 S( \& _) n) N0 K/ D( Y! g/ I
// implementation
$ F. u! E- \/ p ]private:3 U4 c! G0 m6 H1 A% k" }
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
5 o& A) C3 n6 O( X- t* {7 F& a HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);; T$ L: O0 {$ @1 `' g, L
+ H: R+ H7 C3 s8 Q8 V2 E
3 `. k& R) Z: c
private:
9 e8 J7 d) B& S" Z; u% R CUPnPImplWinServ& m_instance; B6 `; `! t% o- ]9 F2 m7 A: g% N4 Q
LONG m_lRefCount;2 t8 v" o& \& |3 g
};: |( O3 Q) C/ N
- q0 R2 V" ?' r4 H0 A% W* J
8 u. G$ N5 X' Y# \/////////////////////////////////////////////////
Y6 Y- Z& l) ?; L b0 c7 h( K( }! i' g w, t& y2 q: o5 z3 F- Z! O
- c7 U: S: m3 T. z
使用时只需要使用抽象类的接口。
3 B* P4 k* A! y. d! ]! nCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
$ u% @0 O7 E/ m1 C$ HCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
% L( z8 a$ c( r. @CUPnPImpl::StopAsyncFind停止设备查找.
' g* J0 M2 _! `" S2 PCUPnPImpl::DeletePorts删除端口映射. |
|