|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
! y7 B# `' e( Q5 t5 w* W+ p& E' _/ a. j$ n4 n
- _5 X" o- c! ?9 K7 w
///////////////////////////////////////////# m0 k9 o- A% o1 v0 F$ |
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.7 a7 G; a# \# h+ w4 z$ u% M
* |4 \0 a6 t8 b4 j6 M
& o" G) i9 ]& u% o6 r" L, ?#pragma once
: M" ^9 @1 {+ ]3 ^' l# ]9 _2 y; d#include <exception>, o9 J, H3 T; p' [5 h! |
: s* }& ], \& s2 t4 Y
* X3 A# R- q% v5 _, z; u
enum TRISTATE{
& e, F7 A7 `5 C X. Y6 Z2 q0 ^' C TRIS_FALSE,
- Z( h) q$ c2 B% E) p/ T- N( E TRIS_UNKNOWN,4 u6 y) y7 R V: j' b* z! T5 m
TRIS_TRUE
$ A. l& }; j% Y5 @" \}; K- W4 T- ?/ n, P3 p' I
1 Z3 D% V0 C# j
& ]$ w. l! b) a, Genum UPNP_IMPLEMENTATION{
5 s* Z* Z8 B" k5 k) r UPNP_IMPL_WINDOWSERVICE = 0,
2 |! j9 @1 O5 m UPNP_IMPL_MINIUPNPLIB,
$ A4 F. B: T2 g+ O$ p- }7 @" u UPNP_IMPL_NONE /*last*/& \4 _* \4 Z0 M, O& t" ^
};4 D# J; d/ v- e o+ r; b. e
6 M" x# U: y7 @) c/ Q% i
r* e) E4 C" u
7 A% N( C! S$ I( d& R( j
) r1 f8 K. v7 m2 pclass CUPnPImpl* P8 G' E2 D! b+ m
{. O2 C1 v/ d2 c8 W; t
public:
% I. b" q) L2 t& J1 D CUPnPImpl();; l$ H7 B, i) I
virtual ~CUPnPImpl();
" E, n. m( C: c struct UPnPError : std::exception {};; p9 ^' z0 Y1 M$ f( i2 V5 D t
enum {7 j2 K0 b- t$ |: y$ l, x* V8 |) L5 _
UPNP_OK,
/ K. _0 E' S9 B2 {* E, Y a UPNP_FAILED,% A9 n- q$ q5 J& f
UPNP_TIMEOUT$ ^8 m8 i9 |5 w* J9 I+ p
};. j( N- X5 ?- }; m$ w+ S' \
: V8 K5 m! S d! x
6 a8 d7 `( Q8 Q. [" E- R virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
6 Q, G2 y5 b5 Y7 ?2 A virtual bool CheckAndRefresh() = 0;5 \3 O9 @& r* _$ j+ `, b7 s5 I& h
virtual void StopAsyncFind() = 0;
/ O; U" @# O# N. R virtual void DeletePorts() = 0;
4 w+ z$ ~* [3 F4 V+ P virtual bool IsReady() = 0;! ^- u2 A, m* r( e
virtual int GetImplementationID() = 0;
9 P! S1 C8 w2 `: p; m
9 B9 f6 U# {. K; D/ v4 _0 e1 O8 y+ K2 N void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
4 C) ^6 O' `& S8 O5 o( h
7 S0 L- O) Y* e. n" o+ B2 \
A* u- m. z6 P; k3 X1 h void SetMessageOnResult(HWND hWindow, UINT nMessageID);
* d" \& j4 j4 }# f7 S( {) L TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }- e$ B1 w( K% H [- x2 x
uint16 GetUsedTCPPort() { return m_nTCPPort; }, v l5 i0 R+ c0 u( N) ^
uint16 GetUsedUDPPort() { return m_nUDPPort; } ; H% a/ ^2 ?2 A# c. Q
A7 n) Q- t% Y/ U; W8 G0 J. D. n0 V7 n5 K. S9 t4 l
// Implementation# k2 d/ y4 Z0 W$ Z0 c7 d
protected:* q- C- k# X2 k* W# d( C. t7 z
volatile TRISTATE m_bUPnPPortsForwarded;
8 P9 I; ]) M( o# l' K void SendResultMessage();1 O2 G+ B5 T0 `; S) E
uint16 m_nUDPPort;
% L7 u/ j3 h( ~8 @ h$ U uint16 m_nTCPPort;4 X- A" R8 | V5 n' j7 V+ k) [
uint16 m_nTCPWebPort;$ w1 p) u" P/ _8 g! U
bool m_bCheckAndRefresh;
/ X" O! s9 m q
/ Y% \7 T! C; v
7 ? m: R3 Q5 K7 C, e2 M Eprivate:' j1 v) i3 B; K
HWND m_hResultMessageWindow;% s: f4 ?) \; o2 |- U5 t
UINT m_nResultMessageID;
5 m7 e% L5 L8 ]# \1 \/ F) e
! y) ]( L/ D! O \3 j1 I: Z& X1 j: I. t1 l, Z
};
* `/ J: \; n, g _' u
' h% L7 P. p' l
+ [( ^( `" @) B& x// Dummy Implementation to be used when no other implementation is available
9 V0 ]3 D7 L. H" m- D. Y+ A4 Uclass CUPnPImplNone: public CUPnPImpl8 h* y- A/ E4 z- s$ T l$ a
{
. D( T5 T% @; b/ p) W; \0 tpublic:
4 F0 @% M" w6 i8 O# z: S& b virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }& h& o2 a( v5 D$ h7 s M
virtual bool CheckAndRefresh() { return false; }
, \5 ~2 ]5 B' s8 I( k virtual void StopAsyncFind() { }, s6 l! h s7 _' \( F% R+ ]: d
virtual void DeletePorts() { }
3 f) ^& V' d0 V: c* T virtual bool IsReady() { return false; }, Y/ z; R0 v/ N6 t/ V, A2 d: [
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
: A9 j3 | {( m: |! E- p5 M% G};
P7 v2 n. m4 \' _& s0 t
5 H8 `" U6 n$ b p8 O
& \8 v; o; M3 o# Y1 G4 ~ y0 y2 l/////////////////////////////////////( L6 m9 D4 B; `" Y8 q: u. p3 Q
//下面是使用windows操作系统自带的UPNP功能的子类
# A% j) @! D0 s
. |( x- y8 Y/ Q* u. ~7 O; p2 ` u0 ?5 ], K! ]. ^, W6 ~
#pragma once
6 b# R3 H; M: g& M#pragma warning( disable: 4355 ): S/ x9 {; n" A% D; {
0 ^+ |- F9 \( I$ I
2 R: I3 z- Z; Y" @
#include "UPnPImpl.h"! ?: O9 K- C4 y7 a u: R2 x
#include <upnp.h>6 j# H! q Q+ W7 m5 R$ p
#include <iphlpapi.h>! X# L o; I, h/ n* W2 m5 J; b* x4 h
#include <comdef.h>) Y- j7 `; O( }; Y' S9 a" J
#include <winsvc.h>0 X/ i& F+ N7 x5 h8 M$ Q
& [3 U) Z! g( U( G
% l' i- n; b6 m% m: Y9 S" D
#include <vector>- p6 f4 R' G5 L6 v: B* L* O
#include <exception>6 d5 I% i2 W, p. i$ D# E
#include <functional>
: h8 T0 A0 P. u7 a8 i& Q3 c
6 M0 Y5 j/ b1 Q$ ^- t7 A9 d2 _
! ^+ j$ A/ W0 u* G- k8 b, n8 N9 x, }0 _0 d, k
5 k( C9 J3 Z2 ~9 b; p2 |
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;4 W; {- d5 C2 q# j* {: J* h
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;) p3 W0 f; A0 Z5 O7 {
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;' P" `6 Z% y; r6 [
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;. ]. y8 d8 U4 x' b3 u
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;6 H3 ^0 ~( S9 K+ L' f& a3 O' v6 k
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
. q3 k9 d1 ?% l' P0 [typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;1 k' J( w" z% m2 P* {1 T( r; F
: d& g+ {1 b; r }4 _
1 X# J: Y( s& E" V! `; b" ]typedef DWORD (WINAPI* TGetBestInterface) (/ |7 o: t* a, W) i T
IPAddr dwDestAddr,4 L9 C, g5 Y/ Y
PDWORD pdwBestIfIndex: q( R Q' ^5 r! P1 B, o
);8 r; m. E c0 Y/ c7 `$ {$ V7 L' a& S
* a* M! D. o* x- Z* c; Q9 R+ W& N" ?2 q% X
typedef DWORD (WINAPI* TGetIpAddrTable) (, T# ]* O- m( [9 E5 _7 p, v! G% h
PMIB_IPADDRTABLE pIpAddrTable,# S" L4 Q, l9 T. O$ |" `
PULONG pdwSize,
% q5 d% c/ k( W; d2 i BOOL bOrder# ^: {5 ~+ ]1 x; D
);/ \& S. S* x& m) V |& J7 z" |
9 I4 r1 e9 Z1 h% w2 H N' c" h
! b* j. Q7 Q7 Z' G0 \typedef DWORD (WINAPI* TGetIfEntry) (, v; ^$ \0 C5 ?: J* n
PMIB_IFROW pIfRow
0 z( v1 t- ~3 R# F);
0 R+ w' z+ F5 z9 E, D% V$ }$ J8 Y; Z# }4 I2 `( g( i! W' F
2 J+ R8 ]4 c/ v* P7 N( g9 r
CString translateUPnPResult(HRESULT hr);3 u o8 W' C) U s( J' d. E9 h
HRESULT UPnPMessage(HRESULT hr);
3 J. O; d7 C5 Q% g2 M" l* V4 p9 d0 H- J. b* g1 ~
* u; z' {* I/ g/ {! u% P6 y
class CUPnPImplWinServ: public CUPnPImpl
) u- g0 P; X. l I5 E8 m, D{3 X d- z6 j3 q. k% S/ f
friend class CDeviceFinderCallback;
: A" A. |/ Q$ u/ R2 D, e* s2 x friend class CServiceCallback;
3 G0 k5 }8 |7 V. u E( D+ y// Construction' o& d$ S( O1 {( B
public:, @! E! Z$ U! b1 r6 f# A k) D
virtual ~CUPnPImplWinServ();
/ U8 s2 @, D2 w- } CUPnPImplWinServ();
7 \* d9 T* t* E5 z( G) k% y
5 l: }$ j* X: l$ K5 L3 v p S
" m3 |0 e" i5 h5 Z# i1 L virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
% h- e2 k! w4 m6 g; M1 R virtual void StopAsyncFind();
9 f2 g( e- S1 Q' Y0 u0 I virtual void DeletePorts();
C0 t! M3 Q- Y# o7 k; w) x virtual bool IsReady();
: Z& M; N# Y; j4 s( C0 E virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }2 M2 k1 I2 T- w/ P) m V A
% Y: k$ y2 r" C
& J# M" ]: G$ Z // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
0 j, n4 T$ F( E4 Y // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
% U( @( L$ i6 n; u. N virtual bool CheckAndRefresh() { return false; };* b6 E+ N% X: O' Y
: U8 y% T( |- c4 \5 @0 g9 N$ ?
: }- b# L: k V+ {" l; tprotected:
) \' ?3 b$ _0 X void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);$ g! N3 h* `' q5 U Y% _8 W2 s
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);3 |; \6 X. R5 y1 f2 C- }) g! I
void RemoveDevice(CComBSTR bsUDN);* w x1 _- ?) A/ r# L
bool OnSearchComplete();" A- Y. O( Q8 H/ H6 b/ Y8 a
void Init();/ q P7 S5 |6 v- g* [
+ p/ @; ^6 b7 }
v! `; c) N2 K8 M4 v9 _1 q inline bool IsAsyncFindRunning()
5 x: \! ^2 Y4 d9 W' j {
0 O. e6 ?# [3 C: y9 F if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 ), ^, c f: }% J2 ~
{
0 X- s* y; P/ ^6 D" S6 o m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );$ x) k) _, p9 I; @
m_bAsyncFindRunning = false;
1 `# M' C. c2 _ }
; C! G" T$ [/ i3 O* s0 d, f& z MSG msg;- C2 V- j2 s* t( R& _; I
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )& C$ r# O1 C. s+ i/ e- W
{
4 H; X$ c0 `' P+ C/ H! v. F TranslateMessage( &msg );6 |- H: k: O+ r1 P8 h/ F9 y/ _9 ~1 B
DispatchMessage( &msg );
& b) x. G- K4 x e }. t W6 }. c& G) y0 t1 K" g
return m_bAsyncFindRunning;& a. X- x5 ~( v4 i( i/ ?
}
6 n% s$ e9 W- `& r4 @. [; L: L
( O" I) f$ a4 L! P, ^! `1 r4 f; }$ Y6 l6 o( d- Z" K
TRISTATE m_bUPnPDeviceConnected;7 |& ~* x2 S' i0 l* V% y
2 {( }* M( ~) G# I& q7 r/ i5 c0 U2 ~
2 R8 j- ?( a% K" v3 C4 R) D+ s: x0 t// Implementation* x) x& {* G: Q
// API functions1 C; a9 [! f( w8 W, Z
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
& m7 B" h+ U; c2 S SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);( g0 j- S; _; f& m- m9 f: x L
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD); ]8 m! x6 C- I, B+ D6 s. ^
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);& \9 Q n3 ~4 { h" B t
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);4 X" C9 S$ ^! @4 G
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
( }+ D) c. J$ T
# x+ B" ?/ L9 v2 P* w' d6 B* |7 W# J3 Z: I
TGetBestInterface m_pfGetBestInterface;
; `) p7 z: [9 j5 g3 b8 U" _! { TGetIpAddrTable m_pfGetIpAddrTable;
" c7 ^/ ]$ m; |7 W' c/ Q TGetIfEntry m_pfGetIfEntry;
9 R8 d1 N# N" V" V
- f& G9 ~. e. q
E8 v4 L d8 ~, l; v static FinderPointer CreateFinderInstance();$ Z+ _1 ^4 u* H/ v. v
struct FindDevice : std::unary_function< DevicePointer, bool >
9 o; i( J7 @% A7 |6 Q {% Z$ M; Y) w/ R
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}5 T8 Z0 I7 v: y k; x6 A: ?" h/ H
result_type operator()(argument_type device) const
`3 j6 l. d' n/ l {
( y5 w5 {0 @7 v n CComBSTR deviceName;
. h b( O: u. L4 |% d HRESULT hr = device->get_UniqueDeviceName( &deviceName );
( d; m* E+ v5 V: L: O, V
' q6 G" p) m0 U- W6 E2 ~. S. } F
o& X+ z; T2 h$ k# f if ( FAILED( hr ) )4 d, Q8 X2 n$ t6 d, Z
return UPnPMessage( hr ), false;0 ~$ n4 R; e% i$ L! K% W
7 M1 F. |) ?# u9 @, d" r' Q5 n) |, A# z0 h8 U3 G3 ~2 t
return wcscmp( deviceName.m_str, m_udn ) == 0;% J* Z$ D* g' ^! A
}
! ^, u8 z' ]0 B( C( k# B CComBSTR m_udn;
& O) z% ?. @ a8 f };: n5 |6 H& V2 \$ {1 [
n7 H* S+ ?4 ~- k$ }, v6 O void ProcessAsyncFind(CComBSTR bsSearchType);
, h! m+ `1 E* U2 I HRESULT GetDeviceServices(DevicePointer pDevice);
$ B. c- Q. m1 z+ r8 \( K" [ void StartPortMapping();+ A1 q) q( }( k' h
HRESULT MapPort(const ServicePointer& service);
% f6 W- o/ Q% W/ U% F void DeleteExistingPortMappings(ServicePointer pService);
, V J0 @6 H. n, [ void CreatePortMappings(ServicePointer pService);* d/ B: ?8 k! T: W
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
6 W1 ]7 \% O- y- y; j HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 1 i' E/ p* a0 l3 f) P
LPCTSTR pszInArgString, CString& strResult);
. z5 }& L( ?' e* F2 X3 c- o$ w void StopUPnPService();
) N3 k0 @. S \! d1 D# k% Z5 J" w# F% e6 ~
& S! V1 m+ }+ [ // Utility functions
: `* U9 h9 W! _( W! ~ HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
0 I; C, @! E/ z6 E INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
: }6 B7 I, t, e7 ~6 B, m2 l- h INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);# p7 `$ L: T4 p2 v, }
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
2 o& f, J0 i6 X$ I HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
# T/ I$ h# d. C; |8 A: [ HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);* D) A& m7 j7 _( z1 V# [/ {
CString GetLocalRoutableIP(ServicePointer pService);
/ t3 E( f' k' w7 b J f( D- B/ F( y! Y+ [/ K6 @
" K# ^' {9 Z" W4 K5 f8 y1 K// Private members& N5 s a5 \! O! m4 J2 d1 w) @
private:7 X: X) c3 v) {' F# X
DWORD m_tLastEvent; // When the last event was received?0 D7 Y$ E. g3 S( F
std::vector< DevicePointer > m_pDevices;
1 N- b2 V+ X: H9 f( ?5 o: o std::vector< ServicePointer > m_pServices;
4 E$ H4 g6 ?$ A$ ~- }4 Y! ?8 q FinderPointer m_pDeviceFinder;, C7 Z/ v( V/ @5 F2 m5 |9 L1 Z
DeviceFinderCallback m_pDeviceFinderCallback;! y3 u @) B! L- d M
ServiceCallback m_pServiceCallback;
6 l! W# E' X. N' Y
* B' L! T D3 }3 u7 S
5 f7 D* }' c* [ LONG m_nAsyncFindHandle;( ?& n, b" S) B& A& s6 o0 d
bool m_bCOM;
& S5 z1 Q- L$ i; t! F$ _ bool m_bPortIsFree;4 B* O3 V% |5 l& N$ s8 r* H+ ]
CString m_sLocalIP;) j( B- c6 D! n2 Q7 T, x$ y- v+ {
CString m_sExternalIP;3 L: x6 D" j, R
bool m_bADSL; // Is the device ADSL?* \& [" A" o, B
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?- j6 Y" x& r$ n; o
bool m_bInited;; M3 K5 b+ x1 ~; V- V- o4 e
bool m_bAsyncFindRunning;) U$ @$ ?6 F5 B9 C4 c. B! v, `# ^* ?4 W
HMODULE m_hADVAPI32_DLL;! u% R6 \9 M% i
HMODULE m_hIPHLPAPI_DLL;
# V$ Q4 I& |' R" E$ w bool m_bSecondTry;
, p" F* Q# m2 b; w bool m_bServiceStartedByEmule;
* [" o1 n. Y* [, N+ n8 ` bool m_bDisableWANIPSetup;; J% |- m2 H; U6 P& p" d. q! [
bool m_bDisableWANPPPSetup;
- ^) K' m" e+ u4 A' e: X: Z
- Z( r5 K9 U0 c, w" D) ` k; D: x2 c$ @0 [! _
};
. O+ ?: z' r1 h* ^) e% O+ [6 ~& ^# V1 ?+ X* c% n; T
; O) O( y" [* q# J// DeviceFinder Callback# q# S. D, n% P, u
class CDeviceFinderCallback
: s" r9 j1 V. D* y' l+ t9 c : public IUPnPDeviceFinderCallback
, @# H9 E* m% `3 u6 P{- Z) E+ c! K8 V: A M! s1 U
public:: `! S9 C! M: R# d9 N: m9 X
CDeviceFinderCallback(CUPnPImplWinServ& instance)& ]1 I+ ]4 }* I7 D
: m_instance( instance )4 }* P" y1 `2 L4 K+ ^
{ m_lRefCount = 0; }
) X: C$ H# I" t
8 @0 y( R+ q5 j, `7 ~) ~* e9 [
) ?9 S0 ~' i; q/ d. v4 l! R STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
) `: V% t2 e6 T STDMETHODIMP_(ULONG) AddRef();8 p( z& n4 e* m, i
STDMETHODIMP_(ULONG) Release();( H- N* T( |9 a
9 y5 H% k. d; S
/ q% e5 l/ q* }9 N5 s0 L// implementation$ F% i5 y: H( Y
private:5 ]8 X: j) d0 U _9 I7 Z" y& L8 W* J
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
2 V# G; f' ~- m HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);- r7 x3 ^4 d/ y A
HRESULT __stdcall SearchComplete(LONG nFindData);
; i4 Q2 q) _0 x
; }, [$ ~* ~' W! X/ N! W% E" A, Q' C2 K7 @
private:
- R/ I9 F' `& r! N CUPnPImplWinServ& m_instance;" B! x5 J# _) C, E% ^
LONG m_lRefCount;
7 K0 x+ p$ F' t* H3 ~* ^};6 Z1 ~ a- y3 U6 j! F1 g3 b
; q' Q$ }$ {# Y0 i( Y4 l' `. s& R
! M2 f3 |: u5 E
// Service Callback
6 o; S# y# }7 D2 f" x* T [class CServiceCallback
. u* x3 W [# h" w9 G, e/ c- L: } : public IUPnPServiceCallback( R. ?. n: x, d& h
{! a% f, {7 |; _, }; p( z
public:
$ A9 b( q1 X9 O: ~/ F% ^! F CServiceCallback(CUPnPImplWinServ& instance): G3 K' ~- w' f; ]. G: N7 F% v
: m_instance( instance )
( P2 N- K0 c8 P }8 b { m_lRefCount = 0; }
& b3 }. P& n u% }7 h 8 t" ]& S- X2 E4 h8 m+ E% j4 V
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);6 |' H) f* \/ D* R7 [8 u) a
STDMETHODIMP_(ULONG) AddRef();# |3 Y. @ \) B2 C7 y+ W. u: b! I
STDMETHODIMP_(ULONG) Release();8 J6 U" i+ H* j1 C
6 r' O$ z3 O+ q7 p6 Z% u% \
. U: W: A! F1 p: b' @' b9 m+ n// implementation5 q4 ~0 \4 |3 `% r8 a
private:7 J' h7 f# f) a2 t
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);; X. r" b+ U: A+ M( k
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
$ y1 q4 e) X0 _0 P7 ?/ Z- ~" T- g9 V" H" p
6 N2 y5 H, N/ T5 D2 D t9 z, |
private:
. R" Y z* W( m9 x' O; ]4 R CUPnPImplWinServ& m_instance;; o q+ P7 o7 A: ^" C/ h+ T
LONG m_lRefCount;
+ X9 W+ y5 [( i) G& ?; n+ y% P};" \$ ~0 ~+ {0 A0 {" e
3 A8 e: N' F/ R( _5 ~# v# c
/ ]3 v$ x @7 q0 x% w/ B
/////////////////////////////////////////////////+ K* T) H$ C7 X3 b3 z
" i' } |4 D$ U9 s0 P- y/ O! _6 ?. q# C4 `% Y% ]
使用时只需要使用抽象类的接口。2 g+ m' n. b" S0 n9 d. h( H
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
% a) c L8 y5 s* K4 L& ^CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
+ X* Y) b$ u9 q; `8 |' zCUPnPImpl::StopAsyncFind停止设备查找./ g' m8 o4 D+ F) S6 F, J2 e3 e# Q. }
CUPnPImpl::DeletePorts删除端口映射. |
|