|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
' s' ]1 p `% v( u9 _& q' N3 x% x t2 b5 ?+ }8 H- p4 C- I
8 y( g: ~0 b6 c2 a# Y& ?8 j
///////////////////////////////////////////, F6 ~3 y6 w. G1 E
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
* \& j* Q* H6 z( u& F) b) C$ s$ n; [# h9 o( @: s& r
. V% a2 x9 e6 v" F5 o" e#pragma once
7 j2 G. N# f- z P8 e#include <exception>
9 X# \; I* d* {2 v6 n5 A+ S/ z4 f/ T6 k J, F' i3 G! Y. `
! [3 s/ ?! }% t: O enum TRISTATE{
, j: Z x: g! O* k5 X8 h# ` TRIS_FALSE,1 h K/ S h) P
TRIS_UNKNOWN, N, C H) u8 f" O# d
TRIS_TRUE
, F- X5 h) A- F, P- N1 x};9 c. F/ _- g: P( i
& j7 X' V9 W5 A* V% e% P
5 }6 `3 j$ e' y. D! b
enum UPNP_IMPLEMENTATION{0 G' k8 b! r/ B+ ]) l7 x
UPNP_IMPL_WINDOWSERVICE = 0,
& o% n K* X3 H UPNP_IMPL_MINIUPNPLIB,
7 ^7 T- y' h3 k8 E* z UPNP_IMPL_NONE /*last*/
1 B* |* g) Y& o5 w7 C, D};4 N" M! o* E5 A& t5 K/ y
/ F4 h' O, S5 s, p7 k( m# V6 g' |: P( O3 V {
0 Z, o3 t- U4 i* U5 {. k/ ?. L2 L0 x( T
class CUPnPImpl
% `4 z. s! z6 y8 z{
: D( t3 `, F2 K% gpublic:
' {: N+ O: k$ X5 j: m" S! X% M CUPnPImpl();
3 z8 v, E! o( ~$ a virtual ~CUPnPImpl();
. E+ `* C# k- J! X( J) ] struct UPnPError : std::exception {};3 X/ Y4 X' N) S, t; ?; c/ t2 i
enum {
9 U0 K: d' @" X UPNP_OK,
! P- i( y2 i& a g, S4 _ UPNP_FAILED,
$ j$ ?2 G. X9 |, }# H: Y$ a, s& o4 |' g UPNP_TIMEOUT; J" M5 R: ~* n7 {% H2 `
};6 q7 f9 @3 b8 f. O; u! t$ G
, {, Z/ k6 x+ o" x1 |" E: F. T; P4 e
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;& c% W$ h$ F8 H; J5 y
virtual bool CheckAndRefresh() = 0;$ S& U4 s6 z% n* c2 x
virtual void StopAsyncFind() = 0;
% o, S1 @3 M+ K v3 a3 w virtual void DeletePorts() = 0;
+ z8 h$ F. W/ B0 ?7 h2 t" K0 l% i virtual bool IsReady() = 0;) [6 W" ^% R/ l
virtual int GetImplementationID() = 0;* y( L5 t/ q, V' O: [1 O
p2 _/ j+ F4 q0 U' E4 b void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping# v( V" p* L7 J3 C. t. u: l" b& t. D
+ _! g8 X0 D7 ^& F$ t
/ [% v" X: Q2 j" K void SetMessageOnResult(HWND hWindow, UINT nMessageID);
4 k) u1 l# ^: e( |8 _; L9 i. m TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }$ e4 M' F/ [1 k' y
uint16 GetUsedTCPPort() { return m_nTCPPort; }8 j) V' R( ], S( X* C
uint16 GetUsedUDPPort() { return m_nUDPPort; }
. \) P1 o8 Y) H$ N+ y" U7 O; u# b- H
2 e u K; r6 c, t2 B9 I: ^# t
// Implementation
8 w" Y3 @9 Y+ Dprotected:( R/ {& g6 s/ }# x0 L2 {8 j+ ~4 |
volatile TRISTATE m_bUPnPPortsForwarded;
0 ]$ g5 b+ r; G void SendResultMessage();
' h* y) b" w# p/ } uint16 m_nUDPPort;1 d1 M; L' B) k k. F5 c
uint16 m_nTCPPort;$ X! z- E* ~4 e
uint16 m_nTCPWebPort;
" k8 P: ?+ Y o+ k bool m_bCheckAndRefresh;; C o1 ^# i2 \! n7 a
4 k% @# O! U# }
0 C3 z# s4 W# D) z) S' `private:, P6 q+ @8 z. g5 z) \/ j
HWND m_hResultMessageWindow;
9 ?/ F {! Q5 Y b UINT m_nResultMessageID;
# @* K; ^0 A8 h V
1 P( A; {$ r1 m9 X% @7 P* H6 H. D! m. G: G& u- j3 \
};
7 |; W1 Z# _5 }. g& C y* q8 {2 W. p+ `) h& J: J% q
5 D! U- r, e ~
// Dummy Implementation to be used when no other implementation is available
$ n0 c8 M! u$ Y4 A$ j4 bclass CUPnPImplNone: public CUPnPImpl' c |% k' S! z
{- \9 v: S# _" b) G! }1 Z J
public:4 U+ D* P! \# U( g
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }+ w1 r- ]$ a& O. E! L
virtual bool CheckAndRefresh() { return false; }! W, J& R2 l b; ]3 i) h, b& Y
virtual void StopAsyncFind() { }
. E3 T8 K: `. N6 E7 C* } virtual void DeletePorts() { }! l7 `7 }% o. \3 z: @* E
virtual bool IsReady() { return false; }
. R0 z D# {/ l virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
8 L7 U; {* |0 p2 U* L/ @; Q};
2 `" x }: W# o3 h' v
/ I! U/ ~. }) D, t; K9 P: R' g
2 I8 @3 \! w, r' I/////////////////////////////////////
4 C" g, a S1 }: Y//下面是使用windows操作系统自带的UPNP功能的子类
3 k4 f& L2 i9 v# D) V2 c& G( Z3 c0 V6 E0 m) S2 s% L
! E9 W) i2 `0 F#pragma once
/ ~3 G# M1 B* b; K* |#pragma warning( disable: 4355 ); c5 _4 T. I# u0 m' |
/ J" S% w) K I5 f4 r& U9 c/ d
/ P' v+ n2 y6 R) l7 ? n5 N2 L. b0 S#include "UPnPImpl.h"
; H3 y8 M0 `0 D8 n; T2 M#include <upnp.h>
, `. F: c, ]5 Q#include <iphlpapi.h>9 ]9 W# X% \# ^( I s: A- n7 A) v
#include <comdef.h>8 }! N- d" W; b( z5 @% ]7 Y
#include <winsvc.h>
) y q# _' n" n
5 y& H& b, v; J" x0 V; J
- o3 _/ {7 ?9 d1 p' F6 x#include <vector>% z) O1 \. r1 t! u/ n' f3 \6 {0 {/ D
#include <exception>
3 q2 a# t2 s3 @: m#include <functional>
5 E* e" u+ T6 b. V# y, b4 H
{3 U4 V. G9 n7 r9 A- t# n( Y _) v! m0 x* h1 ?( E
& y. i7 A# g+ N* l
- x( b9 O7 H' ^typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;) N* ?1 j% X3 ]6 w
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;; Z1 v6 r" V# x/ V- Q
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;; m4 a" ~& q6 W0 V
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
/ X5 |; Z1 \0 J; \% A: Htypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;0 Q7 b6 |5 [6 T' r _
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;4 A/ f- I/ ^ k C$ c' A. y
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;+ e3 \, @" z9 |! A: p" [* A6 H
2 @7 u5 F1 i5 t1 A3 J5 U
V8 W2 H# a' B' m7 H; ztypedef DWORD (WINAPI* TGetBestInterface) (
9 k2 t* Y5 r9 j: Q( ?) d IPAddr dwDestAddr,
/ A6 [) J J. q* {' S8 H PDWORD pdwBestIfIndex
( f/ ~8 u% \4 |0 i3 q);
# Y- H2 [5 u Y2 R2 ~4 n' P- B I1 m0 h
}' E5 z7 k& m4 n8 }1 k
typedef DWORD (WINAPI* TGetIpAddrTable) (
, i% [( L+ [0 @- c; S" N PMIB_IPADDRTABLE pIpAddrTable,
$ \; u5 B5 m# L$ o PULONG pdwSize,
2 V4 [1 A9 z3 ?; c& @% P9 A BOOL bOrder9 a$ ~$ J- g: \: D
);; ?3 q$ |/ j$ T
% q- h7 C6 S) j' Y
& T: f, i6 k4 `- o- { J$ {
typedef DWORD (WINAPI* TGetIfEntry) (" ~% N3 E0 q+ e& Y' [0 E X- E
PMIB_IFROW pIfRow
9 G4 @9 u7 {( u& h8 d% X; r1 i( O);
, ?& C1 m; g2 S I- K0 N2 u! I& m
7 C, N9 r. h9 X2 E
. E* O7 m# x& dCString translateUPnPResult(HRESULT hr);
; j" x d2 K# z( F# |$ J, MHRESULT UPnPMessage(HRESULT hr);/ @4 m' U5 K$ {( S2 M6 ]( a
7 h% r* x5 @) {0 p
7 _! l2 \3 E) \
class CUPnPImplWinServ: public CUPnPImpl
( n4 B8 T3 L% ^* r E& N& T{
# f! E) O& P2 g2 l& K$ n) @ friend class CDeviceFinderCallback;& G4 | Z/ ^+ F6 D6 D- s: S
friend class CServiceCallback;) q$ v G0 g7 ?( G, a
// Construction3 u$ x V, @) V' g; l" L, w
public:6 E8 a [0 h# W$ D1 H s
virtual ~CUPnPImplWinServ(); d2 U4 X# `! {5 a
CUPnPImplWinServ();
3 C- Z0 e# y8 Y% t7 ^2 t5 d/ B8 l( S3 Q$ u" q- K/ Z
( B) W, H+ q* s7 e
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }8 t4 }1 y1 T4 C
virtual void StopAsyncFind();" S& ]& i* b8 {/ U ?
virtual void DeletePorts();
- k# j' [! w7 W virtual bool IsReady();1 S F7 P; t: R( f! A
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }) g3 b; f b+ t) O1 O3 j& x! h; T0 o
" g" m5 a5 p$ m. F/ {8 |- m4 V; L/ Y5 f2 l" k# F3 q) q# k5 k& n* {
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
5 E" A+ H$ F) i // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later. Y; [9 R+ S8 I5 |1 g1 Y
virtual bool CheckAndRefresh() { return false; };
W& R N( D. f! m2 {7 u$ [. G5 m6 u9 P3 U
2 D1 w- o9 W; k
protected:5 L$ \$ l8 s/ o$ m7 Q9 C1 l
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);' e- B" t/ m+ o G: v' S
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
5 C5 j& q H0 n void RemoveDevice(CComBSTR bsUDN);
. b u7 ]( m$ [% M bool OnSearchComplete();
0 J1 }. H9 L5 w; ]7 ~ void Init();
/ _3 t: Q9 P& U& D- M
' f+ E$ s' e4 g
$ m! V3 W$ N6 T- ]7 v5 L inline bool IsAsyncFindRunning() 1 Q# c' i3 m0 z e6 j
{7 n. K* R; h5 J8 s3 U) o
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )! C4 R* ?9 i/ W+ H/ F X' U( f
{, J/ _, k7 s; X( \* P' p% Q
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );- f- B( c: g5 Q
m_bAsyncFindRunning = false;2 q; `4 P' h! O4 Z5 b" b: M% ~
}
6 ]7 @1 s$ {2 w% j/ W' y# n MSG msg;
6 H) X! G" Q' @8 M8 |9 w8 y& r while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
' H3 s' L) T, f7 P, m' n( u {# F6 n2 @- E/ r1 p$ ?3 L
TranslateMessage( &msg );
+ a* O; U9 \# a DispatchMessage( &msg );
% H5 ]7 G# L. K' H: _% j }) D! n$ ~! X7 R# B( B: C K2 d1 c/ V8 Y
return m_bAsyncFindRunning;( y! N$ f# b( t- |. G! Q
}
6 M' b' x# {+ O- u& \/ Q
( g$ O7 {, w, [; U; |) E' C6 D- D# Z" s0 z w' U1 u; j
TRISTATE m_bUPnPDeviceConnected;& f) s: ]1 n, A- |' s3 Q
* Y# A) {3 F* P; |7 ]4 K& ^" u# R( `
// Implementation/ _0 s, W/ G- w, b% I, j
// API functions: w0 ?" j4 A+ B0 F
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
* A" _0 E9 d. z2 Y2 b: }0 \ SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
' n1 G- J) s" n9 u; w BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);3 C$ ~. j' G# P0 F" v, C
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);7 s5 g% h% Y! a/ N6 R$ A
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
7 O& j3 g0 {, i4 `) f BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);' i* q8 j+ ]) E' ~: X' e
7 E2 @7 r* P" J
) |+ o- ~: B. b+ x5 |
TGetBestInterface m_pfGetBestInterface;4 h$ I1 P/ L; _: [
TGetIpAddrTable m_pfGetIpAddrTable;0 b0 E, X2 y* s
TGetIfEntry m_pfGetIfEntry;2 y) ~0 M7 Z2 V% L1 [1 Y" P
6 o: l3 h& T3 Y2 K: O. z
+ @! z) g! ~( `% c. ~ static FinderPointer CreateFinderInstance();1 y* g( W# s; e9 L. L
struct FindDevice : std::unary_function< DevicePointer, bool >
0 J& r ]4 _9 T {. t6 N O/ d+ ~8 e6 ?0 g! Q5 h* G: m
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}9 ~, @0 T# }1 q4 {
result_type operator()(argument_type device) const
6 `& @6 @* b9 y! @! v {
K+ G4 U9 v- H8 p, ^0 ] CComBSTR deviceName;6 D2 X" f# N$ e) q% Q. A
HRESULT hr = device->get_UniqueDeviceName( &deviceName );. q% t1 z$ x p2 {, p
1 C! ?6 P/ d+ J( z8 u
% i+ y. O( Y, }. r) j6 G if ( FAILED( hr ) )
& O1 X: r4 m4 @' \) Y0 M. X return UPnPMessage( hr ), false;
3 ?' V9 M) ^) H5 P. x0 c, w
: x5 v2 r- R2 r( Q' H2 a# q1 |0 C. s/ k2 k+ ^
return wcscmp( deviceName.m_str, m_udn ) == 0;9 w7 y- y+ Q' X3 Y# s& a
}' h0 L3 S+ m, m3 u/ O
CComBSTR m_udn;3 s% v+ G0 V/ \" a
};& } q9 O! K) k6 h
2 O+ M. `2 x, a void ProcessAsyncFind(CComBSTR bsSearchType);' A9 `8 a' I# q* V" g
HRESULT GetDeviceServices(DevicePointer pDevice);7 {0 Z. f) e _8 V
void StartPortMapping();- u* g8 m& a; j* L) E
HRESULT MapPort(const ServicePointer& service);6 M0 X) m/ \/ q% L' l
void DeleteExistingPortMappings(ServicePointer pService);/ f0 b1 V( d' D) Z* F
void CreatePortMappings(ServicePointer pService);; M) s' J, L6 k: G# G/ @
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
& {# p- e0 @3 _) X- a- n/ ^ HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
/ W8 o3 ?4 c3 i; S+ \/ F: ^% y LPCTSTR pszInArgString, CString& strResult);; Z$ M- i8 H, r5 _& [1 O
void StopUPnPService();; o- ~% M. X- M
( [" V- F4 U" `7 p$ f" p
) M; o$ @/ R1 J* s% \
// Utility functions
C3 t) O+ s, H1 d" q HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);( x6 F( d; R; E3 r0 n2 U+ ~
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);- v8 c( [ C. b. j; }! z7 U Q
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
' A9 h; y! [9 s6 z% y) ~+ r" D void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
" `; o$ {1 ?( P9 E. V1 a HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
1 m* N# r% E8 ] HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
/ _2 M# Z7 r) {0 q* W CString GetLocalRoutableIP(ServicePointer pService);
9 y( v! t+ H) s' x+ I. A- d" K# I+ r; s$ O
( T; w6 {% b3 }5 u0 u
// Private members# a" w* E7 ~1 I4 \! o" @0 L } h
private:. @ P9 v* H2 H. T5 `
DWORD m_tLastEvent; // When the last event was received?
! w- h: w% y# ]& {: u0 p, V" S std::vector< DevicePointer > m_pDevices;
5 J9 V3 W% V! E. |, J' F std::vector< ServicePointer > m_pServices;5 k6 s3 O) d: T3 k
FinderPointer m_pDeviceFinder;0 D B" n- Z; W7 F' \1 [$ M2 P" Z
DeviceFinderCallback m_pDeviceFinderCallback;
3 S5 U9 J2 f1 S, ^ ServiceCallback m_pServiceCallback;% P- q% b9 S! @) o
1 _; f; q1 f, n) \. M' e9 G! f" R* W) P, R3 m2 F+ N
LONG m_nAsyncFindHandle;
- p6 `1 f9 G4 A, I1 @- V bool m_bCOM;2 Z3 n) L. g1 e* N) C6 e
bool m_bPortIsFree;
% j) l1 E$ W% C& ? CString m_sLocalIP;! Y' P% t1 Z, Q6 C- H' l$ s
CString m_sExternalIP;
& k2 v h! Z- R, ~7 X bool m_bADSL; // Is the device ADSL?0 F5 f* y# V) ~# G: }
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
6 n' U9 v* f0 V( I" e- [: J! `/ y/ t bool m_bInited; ?' o; h& y1 ]6 R9 q$ ?
bool m_bAsyncFindRunning;9 w. p0 f$ g+ A
HMODULE m_hADVAPI32_DLL;
2 c. _5 C0 ^: H: k/ h4 g HMODULE m_hIPHLPAPI_DLL;
, z6 w/ ]# p1 v bool m_bSecondTry;
. Y7 V y% B* O, [: X) O2 m+ K bool m_bServiceStartedByEmule;
4 s1 a) y {0 Q bool m_bDisableWANIPSetup;
0 w" ]; u p% W$ ?5 g( s bool m_bDisableWANPPPSetup;
& H* w& }1 \( N, R+ c" m9 A$ U0 r8 p" L5 f' q; V: \
* Z! s3 R5 r# Y. [" h
};
& b. q& ~2 V( w, m! k2 ?, C
/ b0 j- L) S+ h, S0 }* L5 N7 I* F
8 X J# j+ v- M, Q' S// DeviceFinder Callback; z7 `9 ]9 w! i# L P M' W! f! o
class CDeviceFinderCallback- _ n1 o. U0 B1 \5 Y/ A
: public IUPnPDeviceFinderCallback
5 V' x& B; l M( R$ t: s{3 u1 E" l+ u' Z3 `) o6 P2 J* N
public:9 q t+ O) q* ]% G5 F+ _
CDeviceFinderCallback(CUPnPImplWinServ& instance)$ b: A; Z: |4 B2 X5 E" a1 B; b
: m_instance( instance )$ S+ W/ \- K+ H( ]7 p' m
{ m_lRefCount = 0; }" ~, K$ P8 S V
( p7 v1 ^, |; T2 T5 K2 U
3 c [( t+ ^* ?- T! x STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);0 f: |) t. K6 B6 } F3 r
STDMETHODIMP_(ULONG) AddRef();( z5 M4 w9 w) b* p( P6 q* a3 }: A
STDMETHODIMP_(ULONG) Release();
' N0 h7 `. A, C5 ]2 l( f! P6 B9 U* g6 M: v" l( n8 u. r
6 N% C5 `" X4 m) }; u1 z7 E// implementation
7 L2 B/ Z9 i" f4 ~private:! J" u! o$ ~( w( A; Q }9 v; [. z5 e
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
6 \1 G4 V. Y+ [ P, |. i- ` HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);% Z1 \/ i0 h' P+ d5 R, N- F% ?- x
HRESULT __stdcall SearchComplete(LONG nFindData);0 \& V1 E0 w) c
2 R: u2 Z! X" m) f1 _5 A k
e- a% |; c/ n% o" D# {
private:3 i" ?/ _7 `( T4 d* d3 ]$ Q/ m
CUPnPImplWinServ& m_instance;( k) K- G3 Z2 G% |) Z3 ~7 T6 Q; K) o
LONG m_lRefCount;! ^3 R: W& p. P& s: }5 L
};
3 \2 w8 p0 X3 d4 {" U( O' \- R4 M! ~- n0 j
, H5 P+ ?9 l, n1 L- S0 }// Service Callback 4 l+ g7 I5 f0 _; J5 A- l6 N
class CServiceCallback
: ^) K$ H6 g7 n5 K8 i, J : public IUPnPServiceCallback+ f9 n8 c5 U4 {. v
{5 Q8 Z: }0 l' u) ^
public:9 s( I7 }% D/ P! {
CServiceCallback(CUPnPImplWinServ& instance)8 l! ~8 u/ p% m
: m_instance( instance )
4 c* n1 Z. d# m3 ~ { m_lRefCount = 0; }
6 x+ E: K$ b; I3 d" Y0 ]
6 r8 ]# i5 h( D% U6 |: |3 f STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
; ~3 e0 C* _# t8 Z* R2 s STDMETHODIMP_(ULONG) AddRef();$ i d+ N' o5 ~! L
STDMETHODIMP_(ULONG) Release();
& }( v% N2 I8 l1 J) |3 v" v- a/ ?' R
: a9 j) @7 R- }( M0 G" y( G// implementation
/ c4 D4 c0 z+ [0 c6 b) R1 aprivate:( ]9 a: X* T5 V. T9 N Z7 \
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
5 M( k0 u: Z- x2 p HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
m. q2 \! e- }. ` n! x' ] {
/ h" n$ x+ `2 ]8 o& s: A- h+ y
; v* g; p" _9 kprivate:0 g/ t2 c0 m0 }8 k
CUPnPImplWinServ& m_instance;
/ J4 F0 x4 E' h/ P LONG m_lRefCount;
8 |: V0 ~* D# Z8 z! q% u};# N$ o; t/ e$ ^$ H4 V2 A
r" X) ]! ~) O! j) V, K) d! W" i" X# t6 h9 K7 K9 }) W
/////////////////////////////////////////////////, L. r* {$ X+ K g
9 V0 u8 \" N, i- u: S+ C8 ]
$ ]6 Z) G) c t6 Q$ I' P
使用时只需要使用抽象类的接口。
% [' d O7 z& g! {9 }' ?, BCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
- U+ S1 I G. s* F4 S! @CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.7 R" B& J- |( V! W ]* x( M8 Y2 ^) x
CUPnPImpl::StopAsyncFind停止设备查找., `! d( w$ \; {/ H$ S1 i e g! S
CUPnPImpl::DeletePorts删除端口映射. |
|