|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,7 [8 M$ ^7 {+ }8 r* Q- [
^. N2 r- u& E/ X" f
6 S( Y& d; p. w( `5 {4 V) [( r///////////////////////////////////////////
! I9 T; S8 [1 |/ b/ x//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.+ x' j1 ^, q1 ^7 w
% T y3 N% P) G' F6 v1 i
2 i/ {! ?4 w& a$ x. p: c8 p
#pragma once- w- w( h$ }2 s% T9 H
#include <exception>" q+ s2 y3 I$ [7 a- w
! w: }" i3 r: [9 t4 F! a
}0 _% K2 @. b- V P) X) d$ ^ I enum TRISTATE{" X4 \7 `4 _/ K1 A- A$ q% U( G
TRIS_FALSE,4 J/ ]7 u8 U5 N
TRIS_UNKNOWN,+ {0 k1 x4 N `- d9 Y
TRIS_TRUE
3 V1 U3 n5 y* j, R1 L, n" o! N};9 ]$ B; r# l( W5 A
7 u' c1 |; m7 G( U
8 _4 t1 Q0 [. C5 a+ henum UPNP_IMPLEMENTATION{
5 [- A& p6 V7 o& u1 G% u7 X- C% F UPNP_IMPL_WINDOWSERVICE = 0,
0 Q$ r5 |/ [! R5 G/ L% r6 I" { UPNP_IMPL_MINIUPNPLIB," D1 M2 ]0 @5 o) V
UPNP_IMPL_NONE /*last*/
* }8 q6 s8 s V2 H2 Z7 C};5 }2 _" ]# r8 ^, Y8 M q; d- l
$ w T) a3 }$ w: p, n7 I# Q
9 Q% F2 H0 m) D. S5 q6 _ ~& Y; B. r/ L9 E" U
/ o6 @8 T: |* p+ l2 N
class CUPnPImpl
& k* d6 C, _& f* ^5 Q* R( `{% M5 | e" V# q* H
public:
" n6 ~) Y7 X* X3 x CUPnPImpl();
/ R6 X2 X* x# o3 n4 K4 O virtual ~CUPnPImpl();
4 N4 c3 i/ e' Q1 s7 c struct UPnPError : std::exception {};
0 i# P3 ~8 t' a enum {
5 x# H8 c; ^& S7 l& ~) c; Z( D UPNP_OK,+ n" y+ n% ]6 \& e! w; c1 F
UPNP_FAILED,+ U, v0 W. r' A0 \
UPNP_TIMEOUT
6 Y1 h3 h' ?' F };
9 q; _. }+ ~7 ^- X( p3 B/ ~. n* r" J- I) r' j. x
# Q7 s1 f3 R" u( P4 ]
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;7 Z9 Y/ o7 ]0 W" J% U5 ^1 e
virtual bool CheckAndRefresh() = 0;
& r' g1 z& P# _/ ]) N2 ?) v9 y virtual void StopAsyncFind() = 0;
: {1 b3 x' {9 Z) l( P1 ?1 o virtual void DeletePorts() = 0;
6 s, l' J r. U. K& G, z# L' s) V virtual bool IsReady() = 0;
8 C$ t% k5 p* {5 S( E virtual int GetImplementationID() = 0;
/ D% K, h! ~4 m & H+ f# {2 a% O o0 ^
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping; C1 D, K. S' V% i) a8 {9 G
$ i5 Q( S1 R- [$ @# S C! G
0 S. r6 K5 J6 k$ O* R$ ?7 B void SetMessageOnResult(HWND hWindow, UINT nMessageID);
# F" x7 k- B# v- _, |9 Y- v( Y TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
" Q H! H$ V( D2 h8 J uint16 GetUsedTCPPort() { return m_nTCPPort; }
+ g' {0 ~# i% c5 |# p# S4 a uint16 GetUsedUDPPort() { return m_nUDPPort; } ( N; s% Q! O6 B9 ?
2 a! n6 w6 v U5 A- ]$ w( D
+ h, m3 f( l! ~# o. w1 _8 N// Implementation
# O/ n! a6 T( l& L. y) Z- M5 Uprotected:2 i' ]2 {. j! @: h& ~+ t; q8 n& q
volatile TRISTATE m_bUPnPPortsForwarded;# z6 \' r3 y: `3 Q( X# Z
void SendResultMessage();
, ~# n7 m- Q8 i' a! m+ B, M5 G uint16 m_nUDPPort;5 \9 T2 b" m/ ^/ K9 Q/ ?+ Z
uint16 m_nTCPPort;# Y; x2 p3 F. H7 h" T) k: M$ N+ m
uint16 m_nTCPWebPort;
, N1 x& P8 ~7 V3 A; o" b bool m_bCheckAndRefresh;
# z5 t1 j6 P) n, c. h5 X4 f+ G- Q' g5 B7 n6 S# Q! ~
+ ^6 j5 f0 `3 |2 pprivate:
: L6 U5 ?7 @( e% b Q6 a% x9 I HWND m_hResultMessageWindow;
' n8 P' V% p/ ^' P; t+ y UINT m_nResultMessageID;, v: Y; v1 m7 M: [1 c# h
6 h- M" A, X7 X P; E
* y; a4 o/ @; f};. e* d+ a$ F( {$ q
7 I5 _$ Z, s- ^- ]2 I9 A2 W
/ a1 k8 A4 I$ Z2 V; h4 Y
// Dummy Implementation to be used when no other implementation is available
' g- V, S- B9 |( C$ y# E; i' xclass CUPnPImplNone: public CUPnPImpl6 I# D' X T. ~. [, O% [
{
( {. M6 P' @3 d/ v6 J6 Spublic:* `1 l( E w3 f4 b0 v
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }) I0 e- w% W) G( ^
virtual bool CheckAndRefresh() { return false; }
5 O, J) v' k5 A" X virtual void StopAsyncFind() { }& F$ p& R1 m2 X2 n" H' Y6 ^8 r( G" d" D
virtual void DeletePorts() { }5 f, {$ Q$ a2 ^, v3 x' C
virtual bool IsReady() { return false; }
! w2 {$ \2 Y* b7 e- ` virtual int GetImplementationID() { return UPNP_IMPL_NONE; }1 Z/ a, U( W3 m* ?3 l+ h
};" V Q# p, O4 z' ~1 A
k; d, O8 i7 s/ D' ]2 N; v' ~7 W/ r
# b' H, `! y! U) q& Q
/////////////////////////////////////' M B2 D( z' n( D* k3 E7 O' P1 t
//下面是使用windows操作系统自带的UPNP功能的子类
% h! J; [9 x4 d) [* t% j3 ?# I$ c: Q+ X: {: [
/ x; a- l) q- s- w
#pragma once
& R7 i6 Q' h. b. p#pragma warning( disable: 4355 )8 ]9 w* J* Z" L& l5 ~2 S0 T/ _
- m+ i3 G% s0 |. X4 q5 G8 A
& m/ \4 {+ ^9 M x, x- ?4 Q5 j#include "UPnPImpl.h"7 S) |, q1 q0 Y1 b! z/ a0 I: i, F/ D& ~
#include <upnp.h>& N! D8 _2 Y2 E; Y5 ^
#include <iphlpapi.h>& L9 Y/ C5 M3 E
#include <comdef.h>; K' x# _& N) ?" u0 U' Z8 v
#include <winsvc.h>' a. k6 h9 Q: C* e }- |, I' O
b! N% ]1 [6 a4 @" Y6 A" s' X/ k) ]
#include <vector>/ r ?: l( Q5 n9 ~5 Y4 q9 F0 k7 z
#include <exception>
* I# p* D. T3 Y4 P5 h1 q3 ?#include <functional>8 n) G' ^* m& q% B& u
' f4 p% z5 [# {4 G! K
" A% T* o5 K5 s, w6 F/ @- [% g( A% W `# j/ Y& @% r0 Z
: G7 A/ @) _: ?8 M1 ^8 d) atypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;1 k5 N. y8 R- E( a9 C5 Z/ Z
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
- D- S( T5 d" U; {# w! vtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;8 w. P2 \7 k& t+ ?( s# T
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;" z5 I" u# ?% _; V% O
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;7 u4 E6 J9 v b
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
+ @6 i1 ^( a6 _typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;/ {: O6 P% \4 z/ a
7 _8 n. P0 b3 \6 [4 R/ \) S* T4 ^' P. f9 N _: o. C) w+ z/ ?$ l$ P
typedef DWORD (WINAPI* TGetBestInterface) (
5 m5 I* M0 J3 q. `" V7 k. Y. n. @ IPAddr dwDestAddr,
1 r) ?: ^# k5 ^* [+ y PDWORD pdwBestIfIndex2 }& p }( h- o0 U; r0 b$ B
);
* P( `# i7 u. P% M7 ]5 |$ ]) ]9 |
0 g; Q' G. H2 J2 I
+ w* W3 Y6 R7 ?( \typedef DWORD (WINAPI* TGetIpAddrTable) (
* k! O! h$ m! i+ W2 q" k2 u PMIB_IPADDRTABLE pIpAddrTable,$ q- ^& {+ E" ?6 W: N
PULONG pdwSize,
$ N5 |2 W3 T4 Y& U2 P7 d BOOL bOrder
- @: g6 `3 E0 \3 v7 C+ C);
, z1 h Z" H- v1 N/ |% p7 u3 r
3 ?2 P3 e {! i+ t+ {* C) V$ Z% l$ i0 Y9 b
typedef DWORD (WINAPI* TGetIfEntry) (
/ P& ^/ H# P! \8 v/ ]. j PMIB_IFROW pIfRow& N* N! e8 c# ~2 S( Y. u
);
2 }$ t2 x4 e. Q2 ?8 [& V
4 c/ l1 v& o8 G7 f- q4 _& V: F0 e7 } v& s( Q
CString translateUPnPResult(HRESULT hr);
2 w; E9 s5 d r4 fHRESULT UPnPMessage(HRESULT hr);
0 O8 V6 _6 T( h2 ]. ^' h7 U) K) s
( q: `1 `, Q x; ]$ Sclass CUPnPImplWinServ: public CUPnPImpl7 D0 g/ P8 m2 L2 S3 p/ j
{" G! X8 X: F7 U5 c' q" Z* F
friend class CDeviceFinderCallback;
+ k8 x% f: h: m2 D friend class CServiceCallback;
7 ~9 O# d* R% ^3 }) a @4 M// Construction
* _& U9 D$ d6 d8 u- S o9 bpublic:
" G1 K% l5 \1 B' h# [. m virtual ~CUPnPImplWinServ();
8 m3 h7 Z3 P* W% @8 D CUPnPImplWinServ();2 u$ b$ `6 J$ \( k' V2 b
" `& O0 ]4 Y+ w4 F: a9 N
5 b6 ]7 p6 V+ H7 v' P7 e% l. J virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }, A# C; c& ], p2 x# L$ E
virtual void StopAsyncFind();
. X; E4 R. m5 d virtual void DeletePorts();6 R: e; O" \9 F% B. `
virtual bool IsReady();
/ `& a7 Y8 a; O0 n virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; } l7 Z8 e. @7 F6 l6 Y+ y& l. E% u$ R
- {9 B) H1 R8 C+ j3 @% M
! u% d! p: p( `1 U- z( r& H // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)4 I' T; H) Q' ~# h+ `. |/ N
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later6 g! u/ |* ]3 }, O4 p
virtual bool CheckAndRefresh() { return false; };
% O/ \5 n0 L. C' V% m
; _% I$ \0 Y4 d! L& b& B$ B9 l8 r* O; b; f5 P
protected:
5 c& a+ @/ I! [0 Y+ u9 } void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
) \4 P- l+ z, R7 B- \ void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
& P3 R; P1 [, V6 L, R: T3 u void RemoveDevice(CComBSTR bsUDN);' w2 k# Z! `6 _( c" z
bool OnSearchComplete();
5 e: f* ~. B# P0 S! v$ i- s void Init();
5 s6 y& ~* J! g5 H$ Q: e
7 s1 X9 t B$ G1 g! m& @ x% y+ S: |; {/ C/ {$ w- k
inline bool IsAsyncFindRunning() 4 v& C ~- X/ q' l% g
{0 I4 h) H1 n$ }- T0 ~6 ^0 ]: |- [3 J
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )5 q# j4 Z7 b& }- d
{4 {" W( c* ^# i0 Z0 g+ a
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );9 b1 P7 N9 e& L9 i A* Q
m_bAsyncFindRunning = false;
! T% O2 E6 f. P1 c; {% v% b) x } T# U% d; z* f1 ], T& P7 n. v" j
MSG msg;
1 P U8 t# a6 }1 i! z$ n6 ~ h* l- C while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
0 H' r5 K1 N% |. I' X. D5 a2 n {
" A6 g% Q/ B- i8 x! T TranslateMessage( &msg );
9 {( d* }8 x0 A' ~/ O: O. T DispatchMessage( &msg );0 o& x9 _/ D" B. q s
}
' r8 `! e4 k5 {# _/ a: P return m_bAsyncFindRunning;' C" n6 h4 T' c/ H! q
}9 o; X5 h6 J4 A3 @8 X! l4 A
9 _; B" ]2 e4 j0 r% T7 j4 ?5 l2 {
TRISTATE m_bUPnPDeviceConnected;
# U8 N7 b1 ~. `" I" M! \' B* Z) u( w* m! h- G/ \
( h4 N! y4 U3 Y* @4 g" L* ?) V
// Implementation
2 @' R* q! s4 d // API functions
: M' o. w) ~8 ]; o SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);0 r6 N0 v& }+ `: J
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);' q0 b- j# m- [& y! b
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);/ A! E/ G. @* G5 i3 `4 m+ }" x
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
/ e( o0 l6 i: e9 V8 O8 @7 s BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
1 _# B+ z, ~, O2 H& Q9 ?9 ?# u BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);' s5 R2 u1 a5 o) P# c! K
* F7 K* I1 g! J6 L% q2 P) C: o' @7 s: u" c, U
TGetBestInterface m_pfGetBestInterface;9 Z5 B: `( L( s5 \- C4 B
TGetIpAddrTable m_pfGetIpAddrTable;
& P/ I8 q2 I7 c3 c% h7 Q8 A& O TGetIfEntry m_pfGetIfEntry;' p& g! l4 u3 x. x+ t
. W* R" K1 [0 d" b8 U
+ u# ^$ ?( n7 ?/ {
static FinderPointer CreateFinderInstance();& r. W+ z" P; U0 ?! K5 q0 x
struct FindDevice : std::unary_function< DevicePointer, bool >( \2 c' X5 f- u% h2 [
{( @# B6 W1 x6 F
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}4 x2 n' g" S1 Y0 r& i% K
result_type operator()(argument_type device) const5 U, y. `6 D: _! X! q4 \8 T" U, J1 b
{
1 G, J/ o; z* D+ Q& j" O CComBSTR deviceName;
4 L4 C( b+ S( f/ G: f2 O( `- u HRESULT hr = device->get_UniqueDeviceName( &deviceName );
& a7 R. v5 o4 o! W6 ]7 F
/ ^. M4 ^9 g+ [5 Y3 e
2 l* O' z R T4 ^ if ( FAILED( hr ) ); X- `; G! R3 m6 _# E/ Q
return UPnPMessage( hr ), false;6 o& F y( w3 W: b7 g( d4 N
6 _. c1 H2 S+ ~8 K2 h( o3 q* @
) e. @3 _0 A# F) U: U3 K! A return wcscmp( deviceName.m_str, m_udn ) == 0;
- M! S t# W0 W }
# g: ~5 I k6 O( K CComBSTR m_udn;
. I+ z, ]/ W3 E, Y };
& j* u6 L, ]4 K: y# J+ n ( Q' s! P6 R- o& }- K% v4 Y
void ProcessAsyncFind(CComBSTR bsSearchType);- E! |0 _+ _4 q8 L4 s0 l
HRESULT GetDeviceServices(DevicePointer pDevice);
! ?0 F; ?4 ^0 ]3 p8 \' s5 B void StartPortMapping();0 c9 L5 O( z; v4 y1 ]/ s
HRESULT MapPort(const ServicePointer& service);
! w9 k& T9 q% M( s void DeleteExistingPortMappings(ServicePointer pService);+ K& g D8 l$ t' A) ?
void CreatePortMappings(ServicePointer pService);
( y5 }: U) ?' V0 h' ^. e HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
: N( b0 y# }/ ~# E/ K HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
7 E% ?! R. C' D( ]: N+ N+ b) O LPCTSTR pszInArgString, CString& strResult);
) l; B# {( c1 a void StopUPnPService();4 v ^/ G4 y7 K2 q! X& N
% @1 r" Q6 r9 Q3 L
0 b% Z1 H+ a! F- u6 e // Utility functions
5 ^- H3 X- I) z, s$ \1 j! l HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);1 g& c7 s# ]& p' s7 K2 U
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
% K. g% R" r9 O4 E8 c5 Y6 f$ o INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);2 K. {1 W7 p" ?" l
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);4 E/ Y) W& D4 B. y0 s
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
! _* Z3 E5 l q9 y0 v HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);* D7 |; ?; y0 b0 [$ o+ ?: t. F0 H$ r) h6 E
CString GetLocalRoutableIP(ServicePointer pService);
, h0 X- G* b$ \; F, q1 r1 W3 D# D8 d, a6 X* x+ g
+ u4 I- H0 q; I. E* i
// Private members
3 s' b* c D+ u, X' [private:. Q- b$ H C' ~% i
DWORD m_tLastEvent; // When the last event was received?! U# q: P( ?3 ~- M. Y% Q0 S' |! F
std::vector< DevicePointer > m_pDevices;( Q {" O, _& i4 Z4 R
std::vector< ServicePointer > m_pServices;
: }( n/ B& J% O: _ FinderPointer m_pDeviceFinder;5 w! v2 ~8 D- ~$ r" p
DeviceFinderCallback m_pDeviceFinderCallback;( _2 \3 r& i7 Z5 W) |0 ?9 ]
ServiceCallback m_pServiceCallback;. Y% t6 S4 A' _
; t+ b# l: e( u* P7 o; T$ P7 B+ c3 d: e6 Y. h& G
LONG m_nAsyncFindHandle;
- S0 C" h/ \: w& N! F bool m_bCOM;# Q" B$ N4 P+ l. E* H6 `2 k5 u. J
bool m_bPortIsFree;8 \* F8 L3 _- P- p& h1 I& S4 A
CString m_sLocalIP;
% [0 X1 C4 j+ A+ _' g* j6 F CString m_sExternalIP;
* w6 g% s8 X4 ^# P9 c. `8 q bool m_bADSL; // Is the device ADSL?
2 {5 w: z0 g8 I0 G bool m_ADSLFailed; // Did port mapping failed for the ADSL device?" N, Q& v' d5 W' K( H
bool m_bInited;4 p8 G) E3 A& _# t @1 O+ B
bool m_bAsyncFindRunning;
+ c! k' N& Y) O4 v HMODULE m_hADVAPI32_DLL;
6 I. V' |' n3 R, ] ? d HMODULE m_hIPHLPAPI_DLL;
. O c* g" @5 j4 `, x/ z$ [; c% | bool m_bSecondTry;
9 `5 G" Q; D9 q bool m_bServiceStartedByEmule;3 t, @$ o$ C7 W0 X
bool m_bDisableWANIPSetup;
& r; n) t# ~3 a bool m_bDisableWANPPPSetup;
. ^5 W4 d: e$ K1 M& m* s3 N e8 Y" u X! d
/ |& r3 r$ y; M1 Q& A$ A};$ {9 Z; G: s5 T4 v# Z4 ]
; I2 [) A" Z+ ?
- [- ~3 k0 e; B// DeviceFinder Callback
2 }; A; q; @" W" Lclass CDeviceFinderCallback
3 R, u0 k4 X* `" w2 K) _6 m* Z' I : public IUPnPDeviceFinderCallback* n1 H! ~8 ?& Q
{
6 W/ @9 g/ g9 I- W" m+ Wpublic:6 t- U: n$ Z4 I3 G1 y2 r
CDeviceFinderCallback(CUPnPImplWinServ& instance)7 j, h" E. s3 ^8 p$ x, ~8 S
: m_instance( instance )
; ~) k. M, e( |" q) h& C6 t( E { m_lRefCount = 0; }1 @+ I+ x0 Q Z( N# f( |8 L8 y
' B# j4 o4 G3 A8 m7 _1 b& \, H2 E) B4 {6 _- s' H/ U
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
/ t: a8 \: C5 M STDMETHODIMP_(ULONG) AddRef();* i" \2 P4 S- s
STDMETHODIMP_(ULONG) Release();
) t$ L6 X. k; w2 }) A$ R1 Z9 V9 O0 o& _, U6 D7 `0 \- `
, u) ~; f, a& g) q
// implementation: H: ]" Z) ~+ w. V5 u0 E2 Z, N: [
private:
( B! N1 H5 F3 D. f# ], W2 H HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);" Z6 b( B' Z9 e& r
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
: N: m0 w+ _" v: X& ?. f2 B) G HRESULT __stdcall SearchComplete(LONG nFindData);
0 N( G) Z5 s2 @8 O4 j0 v `( |* t4 L+ A4 @, h" p% y+ l
. P4 |4 J5 {9 p7 O0 dprivate:
3 ^# O- a) f- G$ ?$ p7 U3 ^4 N CUPnPImplWinServ& m_instance;2 Z+ l( X2 @! R( a, P0 F
LONG m_lRefCount;
: d" K( U I+ W( E8 S, t};
1 q. |& [! g; L- h8 B J$ n/ `0 \$ }7 t/ V% ]7 u3 [, |
5 q) ^% P6 J. ~ v+ p
// Service Callback 1 g/ Y) H+ Q/ s# E+ q, y' ]( R: J# T
class CServiceCallback# ?2 N7 S0 w, G8 K5 f/ X2 K
: public IUPnPServiceCallback
6 ?$ @% l: n$ {& \{ M) E* e4 J) P$ r- Z8 A
public:
9 P0 k& j9 E9 J0 l0 K CServiceCallback(CUPnPImplWinServ& instance)
1 W" v- o0 c. f# | : m_instance( instance )
/ i0 @" V/ ?! T7 ~( B; m3 t { m_lRefCount = 0; }
$ F2 L' r& _0 ~( H, H 0 ]+ m5 ]9 F* F/ `9 \
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
n1 d1 } @0 p2 X, L* f( K1 D STDMETHODIMP_(ULONG) AddRef();) P+ ?! k! n. ^! ?" Y
STDMETHODIMP_(ULONG) Release();
: v. g. j, V' V9 r9 X& Y; y7 w; r3 Z6 P: q) Q9 E- T
8 z9 r" _7 l0 N5 d1 E. ?// implementation9 n- U' t& j; o- b$ h. N
private:
( |$ K! b5 i# @) J HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);; c7 N; }, R5 K$ v
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
v( _& h; P- y8 `, x1 R
9 I1 x5 E) \" ~$ I
6 E, [) R- E6 _3 mprivate:; n# w! {3 ~' m
CUPnPImplWinServ& m_instance;
! ]; R3 `' e2 { LONG m_lRefCount;# n: o4 `3 R% T, Q8 R/ Q2 a
};5 ?( J9 l9 n1 ?9 `, S& H' O/ L3 t
. N( _& \5 s: H% \3 v' e q6 `
1 a: c9 g$ p5 B- [5 x1 H! x/ i/////////////////////////////////////////////////
" Y: _7 t' U! G' X" T, a4 h* l; Y" s f) `
4 b8 D# E4 Q% a' w& w1 ?3 `使用时只需要使用抽象类的接口。" L5 O# u- g) e, N+ r6 W Q
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.! c5 M; {2 L* T- z3 P5 p: z
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
8 c, q9 Q3 q& p5 p8 l- iCUPnPImpl::StopAsyncFind停止设备查找.
. w7 T' D |8 s! ^8 m/ oCUPnPImpl::DeletePorts删除端口映射. |
|