|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,% ~7 E5 h1 n2 l2 ^9 U Q4 i
7 J& D: r1 H6 R' h/ D4 j. ?3 ]+ A5 u. m! h5 p
///////////////////////////////////////////, I0 G a' ~- h3 n
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.2 A8 U/ X! ]1 ^, U# A
. {1 Z: Q$ O$ U# {
- l0 g3 k" |* u' e
#pragma once
* O3 x" k0 `! G$ ?/ F: l( d#include <exception>
1 V- q* {9 s* ]% B* ^# v* I: o# h8 X+ X# G4 t/ B
, S3 g: `+ i0 k* m% W2 P9 K) g
enum TRISTATE{' K5 K$ B- l- C( K& A K
TRIS_FALSE,, H; v) O* D+ i1 a: F
TRIS_UNKNOWN,1 r' P6 b0 V5 U4 ]6 H! r; E# J
TRIS_TRUE1 ~: a/ q, B- I8 z% U
}; ~8 Y1 B0 L) D, Z+ t
) E% H% ?* v1 I2 f7 C H! u
( W# \2 N6 Z8 G( E
enum UPNP_IMPLEMENTATION{! T6 B/ K9 d" c' L
UPNP_IMPL_WINDOWSERVICE = 0,
2 H1 I) U* C+ ]/ N0 z5 }1 R& i! s8 T UPNP_IMPL_MINIUPNPLIB,
m$ m+ l8 y& ~8 r9 T9 ~, m UPNP_IMPL_NONE /*last*/; X& _* ]0 g: D7 Z
};! v! @" t3 R3 B3 l$ e3 f2 Y
5 C9 h9 H9 m3 a! V% l0 N5 ?, r( u) `! S4 ?/ W0 q: {$ {
! ?/ [5 D& X F/ a/ V
1 c$ g5 T; Q4 J1 I- F0 V) [class CUPnPImpl
/ P5 B8 ?6 t) Z$ H8 v. F9 ^8 j x{) Z0 J4 Q& q( m
public:! L Y' B5 s0 }/ t6 V. A
CUPnPImpl();( `2 ?, h# y" z, j
virtual ~CUPnPImpl();
5 X) a- b) _. S0 U# A2 ` struct UPnPError : std::exception {};0 c& y& B T t. N, [( S( V
enum {
R/ U6 w# w" u- q* W9 O- | UPNP_OK,2 A5 k( S+ A8 K/ M, w, G
UPNP_FAILED,2 @8 W( i' Z' m v! ]' P6 l: a
UPNP_TIMEOUT; Z% a$ p' n/ u k# I
};. Z$ O+ w1 f+ ^ c$ g
8 R/ Q3 H$ R: e; o! S4 h: S3 H! i$ D; C6 H4 K6 F' m9 B
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
; k# A4 e$ O8 ~6 H* w' H virtual bool CheckAndRefresh() = 0;
& @) H9 b _& y. ]% [+ u virtual void StopAsyncFind() = 0;" [* i* X& m" q! a% j$ [2 a
virtual void DeletePorts() = 0;1 |& K0 N: } p
virtual bool IsReady() = 0;
$ y3 \2 T r: `4 L) J0 a Z3 r virtual int GetImplementationID() = 0;2 E' R) m$ Y: R% u: ?, r2 c
Z6 ~# J9 @: m5 U3 k Q$ m
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
: u9 e6 r1 i0 \: ^3 F: H7 S5 y/ {
' q3 X' n1 k% W$ O# l! C. c' m* f0 j1 c( s+ k$ ~, D1 T) R, a
void SetMessageOnResult(HWND hWindow, UINT nMessageID);9 I( b1 `9 h9 g
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
6 j9 j: [4 m, N, I; ~5 e2 [ uint16 GetUsedTCPPort() { return m_nTCPPort; }. m9 u5 j% T8 Q
uint16 GetUsedUDPPort() { return m_nUDPPort; } 0 }7 |3 M# v+ {1 n N
5 q$ i* e' s j% o6 ^
6 J ~# J6 K' s3 ^8 S
// Implementation& T- n3 i- |. ?0 M/ |) a$ E+ `
protected:9 z8 n. c, m3 Y6 ~* R* X1 u# P0 {
volatile TRISTATE m_bUPnPPortsForwarded;
; V" v3 D5 t2 f2 L% G! C8 ~ void SendResultMessage();
, E8 m5 z5 z& } uint16 m_nUDPPort;
" P" X+ F; E/ p/ p- a uint16 m_nTCPPort;* j0 x& U% T; h3 v$ ~$ ?" @ i; P
uint16 m_nTCPWebPort;1 ~5 n, G( O* `# ?) k
bool m_bCheckAndRefresh;* w' \. w6 ?: w' v
" P7 n7 O* l3 w) e
" K! E9 B3 H) K+ M( `
private:! s* Z0 U {8 H" u
HWND m_hResultMessageWindow;! E; p3 p* p* S
UINT m_nResultMessageID;
7 `. T, f4 J7 n2 I }$ m
8 m4 s' N6 u' I* @6 J: P# f7 P! V& A* b; [7 P
};2 v% P4 ^: U# m" \ N; f
8 {/ a1 w: l# k$ t/ M; K9 U# r/ e0 M
% V, P0 }. q5 ~! o; t" p' E- p// Dummy Implementation to be used when no other implementation is available- ]/ [# x: {! r, z
class CUPnPImplNone: public CUPnPImpl
, q$ s' J$ r, l{
, G3 S0 M" T. |5 s" O6 D1 [; \public:
! R+ _( O; E2 s' } virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }6 z6 v5 G$ A/ i; _0 n9 O4 r
virtual bool CheckAndRefresh() { return false; }4 D% _8 J3 a) K1 o6 L2 I( ~) a
virtual void StopAsyncFind() { }
! k" ]3 e8 Y! X3 ~ virtual void DeletePorts() { }
p1 `" e) a {) { virtual bool IsReady() { return false; }
! O. a& N1 q) h virtual int GetImplementationID() { return UPNP_IMPL_NONE; }0 k: f/ h8 ]8 d+ a3 U, ?
};7 o- j0 e1 s/ o2 ^4 @
+ p' j9 `1 O j: \4 K7 ]0 ^
2 U5 t( w6 V& u/ \# A/////////////////////////////////////' C: T# F1 l& V$ o4 u8 V
//下面是使用windows操作系统自带的UPNP功能的子类
: ]* Z) R* `7 D! `$ F* \8 z
" O# B0 E6 h: U' T3 A9 }5 V, E. T9 u {
#pragma once
8 w! |4 ^1 f. f& S. \#pragma warning( disable: 4355 )4 g5 K" A7 P* v; M
* M" v5 j3 O1 x- [9 g9 x& D3 P7 Q4 m! z
#include "UPnPImpl.h"0 J& ?4 F; j7 O8 |# Z5 ]; e0 x
#include <upnp.h>- Q2 u( C" F. P4 k. C6 }% s
#include <iphlpapi.h>
& `# A; |1 |) d$ V#include <comdef.h>. [6 M" Y+ y4 |! {
#include <winsvc.h>& L: T+ b; N9 h( W, ~* w2 f
7 M# Q% c) S6 f O/ K* q3 x; l
, G% D5 V0 Y6 r+ f' s#include <vector>
1 }3 D+ y) r% H* J9 n8 Z0 p#include <exception>0 E3 U' H; O, h! l4 d0 D7 D, w* i- l
#include <functional>
* S. k9 C: T; Z5 y N0 b6 k0 W0 }9 N9 c, c: I `, H0 k A- _
0 J" K) d: C/ |4 \3 s. @9 ]; g2 t( D" W) f: _8 x- k5 c4 V9 [1 X
2 R4 _1 ?2 l6 `# ]. x
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
+ m p8 W* l, X: c' X- o) Jtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;3 l% D# Q0 `/ K4 w8 @7 g8 m
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;! r/ d% R6 r% u/ ^
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
, l+ F/ @$ W- X) z) S# Jtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;: |8 _4 V4 d2 j. l! G4 X" }+ d
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
3 S9 F9 B* t7 {8 W. Dtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;3 r& i+ {5 y/ {: @$ {
, Z3 b Q, M" \1 e' {
- N" I5 h: T% N. C- o& Otypedef DWORD (WINAPI* TGetBestInterface) (
. i4 X; b y) J/ P7 |7 [ IPAddr dwDestAddr,
4 X5 E: y5 d; c" o2 o; U/ e PDWORD pdwBestIfIndex8 o [+ e( V# ^3 {
);
9 T( W* l6 }$ s& M4 \+ @
3 E6 I3 W% {# H9 f0 h; ~7 c( e7 d+ d" u, s, ?
typedef DWORD (WINAPI* TGetIpAddrTable) (
5 |, H( D: V# b: I5 i6 Y0 ^# e PMIB_IPADDRTABLE pIpAddrTable,
! P' j2 @8 S/ N/ M% f PULONG pdwSize,
" v+ o# ?: Y0 d/ Q BOOL bOrder3 ^% M: x; ]/ E6 X1 z$ J1 L5 C
);
! V7 Z7 F* \& c2 j
7 f: g% e# g/ ^ Y/ H# k& ~" N3 W# C" O
typedef DWORD (WINAPI* TGetIfEntry) (
7 s; M' A6 z% ~6 ^7 N PMIB_IFROW pIfRow
7 R- k6 k& }' {' F$ S2 ]);' _' E) s2 ?6 s9 Q7 b1 d
5 j) A1 o2 }( N4 d. C2 Q; _
6 U/ X h8 N; W( v4 V4 B: vCString translateUPnPResult(HRESULT hr);
+ [9 @+ \. v' x) R' P0 j7 D8 o8 Z% BHRESULT UPnPMessage(HRESULT hr);
" j* s$ W/ R5 c6 }
# o0 V+ K0 K+ D5 p
, q; ~$ p9 N+ l) n: Qclass CUPnPImplWinServ: public CUPnPImpl
! Q2 G( w0 }4 a( k9 o+ H{7 ~/ d; m' I0 g5 O, M
friend class CDeviceFinderCallback;- s3 b3 u: Q9 w4 C5 U3 G( p1 a
friend class CServiceCallback;
2 a4 W& ]2 [7 R R$ H$ c0 K# ?// Construction' W& m: {; W* z( }* K" G! P3 e9 K
public:
; [& s4 w% H: B1 D0 ]! t virtual ~CUPnPImplWinServ();/ m7 q8 U3 k% ]$ N5 m
CUPnPImplWinServ();
3 {+ J3 j& q( ~7 L9 u& b" G; e
9 f* Y2 S3 b: M( B# H( ^+ I# A% w ^% y7 ~4 I
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }/ L$ R# c' [% Z* K# q: I) Z$ M. W
virtual void StopAsyncFind();. `1 {! @# u- g) M2 y
virtual void DeletePorts();8 |& c; B3 U$ c2 h$ C" H5 a
virtual bool IsReady();! S5 T1 {* D' k* D: T
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }8 y& |# S8 h4 u3 x1 q
/ R# u% c! Y. v5 }' k
! [; U$ v3 n) p4 u: z2 x1 g9 c0 ?
// No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)) b2 U; u; _0 h7 B$ U1 X9 N
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
* S. K' V7 q& X: j% C/ p4 x virtual bool CheckAndRefresh() { return false; };
8 B( C+ L) r: a4 ?
& [# G+ H" O: R f5 m+ T3 I7 i, [! f4 f u( l! ^. b& C5 R: H. s) Z! I# N
protected:) F$ y* N4 q0 m3 k5 D
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
# r- j; S1 z( ] void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
, w; s% Z' k9 `/ [5 d1 J void RemoveDevice(CComBSTR bsUDN);: e/ d! l$ ]; ^: o0 S7 H; D6 Z9 F- e
bool OnSearchComplete();/ z& a, @; w Z4 O2 f' _/ o
void Init();
# d0 p4 t3 t5 \/ C/ e4 ~/ y. b% B8 ]2 f
' n+ f% n$ L" [- L; e- h
inline bool IsAsyncFindRunning()
( B" d! b8 _9 J* F3 [3 [ {- ~. F$ C% u" } P% g4 Z; w3 y
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )" i, [4 V# ]. P3 L% W7 U
{5 O6 j% e0 F4 f6 z) d$ p+ A: h
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );5 q" j/ G' e3 P$ [
m_bAsyncFindRunning = false;
3 I& J' e- |/ s4 y }# ]2 i! {5 r$ e: B
MSG msg;
9 i& h# f" d& e- { while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
% ^8 F2 M) J( e, A* _2 G- L& m) P {
! s- A N) u T2 i0 Q( \' G9 y TranslateMessage( &msg );4 D0 P# v Y( K
DispatchMessage( &msg );
) p6 @: m8 y3 V; u2 q }
5 T8 X- [! j5 f return m_bAsyncFindRunning;
$ h+ x- h0 D' }- H* M# M }
2 g& b" E& L i! K* i& o% q3 @! q/ W& B! s* F1 e& b) i
4 M G: M" x5 Q( W3 L9 ?2 k1 O+ u
TRISTATE m_bUPnPDeviceConnected;/ X/ \0 }$ l z! S
: u: r5 b! v6 w8 n9 ]
; x4 ^0 c' H2 v% N// Implementation6 Y3 }6 x+ V, O8 R1 T+ e, u! w/ F
// API functions
, k/ ^" q2 m5 S0 h9 R SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
5 W6 S% K9 N# s: V) G; t1 N SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
: l a. S$ C4 a4 S" W BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
2 z/ ~+ j9 F4 i- o8 m* Q% [ BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);) `3 A) W- H9 [( Z) H
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);4 K# W3 \9 _ i! P( n" ] b
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
1 y" X) Q) ~ g& z' [0 ^( y% p6 z# P. P/ a6 X5 R9 b" F, J
3 \# Z* \" N% F0 b$ ?
TGetBestInterface m_pfGetBestInterface;* g2 G: h' v4 c2 u) v
TGetIpAddrTable m_pfGetIpAddrTable;: G5 m! G% z5 g! O6 u6 n
TGetIfEntry m_pfGetIfEntry;8 ^5 `$ ?# ^- \ _1 G# W' S6 a: E/ P
2 @8 K B( L% C) ^4 h- C& Y2 f
2 p5 E# m. d& \# u5 U; x. V static FinderPointer CreateFinderInstance();
9 c2 ]3 N, x$ j R1 H8 m struct FindDevice : std::unary_function< DevicePointer, bool >
3 F/ o& F1 t) {3 E( [! ^' K7 S" _ {2 ~2 g% H3 ?# a7 [9 X2 K' A( X7 y
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
$ N) y- l* j! Y9 h8 i4 b3 g result_type operator()(argument_type device) const
( B7 v1 _+ D( {; u. a4 Y {
* z6 s* c* K' [/ Q' f) p; ] CComBSTR deviceName;
- B$ Y0 Y0 t% O9 ^+ X" d' V* e HRESULT hr = device->get_UniqueDeviceName( &deviceName );9 C- Y% l V' \5 e4 k# p. F
( ~8 q. m, V4 z9 w+ \( T$ U% M1 @# {
5 L b, g4 f2 i2 O7 ]% ?
if ( FAILED( hr ) )
- P$ Z% F! G2 C$ H# D1 B A return UPnPMessage( hr ), false;8 j, V2 l5 Y1 r. I8 O
4 R/ U9 K' l' _! h u6 W$ p; x$ w9 G0 o3 L
return wcscmp( deviceName.m_str, m_udn ) == 0;3 o+ l: ^: y1 H0 J6 n4 ?( K- v
}- A! O0 I8 v4 } W
CComBSTR m_udn;8 d$ z! j) I/ Q: a5 n0 z, d
};0 I$ F; z) z& e7 p! y3 q/ v$ f% u
" S1 b) g! D" M' _$ D5 R9 @ void ProcessAsyncFind(CComBSTR bsSearchType);- V0 Q5 |: E0 L% p
HRESULT GetDeviceServices(DevicePointer pDevice);
9 o4 [" q# G0 T9 P/ \ void StartPortMapping();" _. l6 ?! _! z E5 q/ X
HRESULT MapPort(const ServicePointer& service); X- L# \' G+ P/ |6 `- Q, f% t+ @6 i
void DeleteExistingPortMappings(ServicePointer pService);
2 [# u8 l1 X5 _ void CreatePortMappings(ServicePointer pService);) } F* X' [( [7 c
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);8 ?( G/ @# C% B1 ~
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
3 @; e0 C2 j: X. c8 Q" ~5 R* k LPCTSTR pszInArgString, CString& strResult);1 e! g2 w& M3 A9 r& ]
void StopUPnPService();
2 x) x: q1 @( |0 X" f4 r! @ m+ Q5 z8 [; [+ j: F* O: H
) P+ p( J4 c( ]% V1 `- ~# k8 f. z // Utility functions
- p4 R; `* F& X; @4 x1 N' f HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);) A& n6 X7 W- [1 z) F
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);( u0 w% b) h9 H% d
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
1 `4 }2 E# d- q7 m4 E, v2 g void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
( c, u& w5 f5 [ HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);5 o; Y2 X, b0 X& s" y# s \! m
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);5 Z+ M8 V9 b& h a9 n2 N- O% a
CString GetLocalRoutableIP(ServicePointer pService);
% U3 g! w/ y- l/ n- C4 H9 B9 T% Q8 I
6 C7 ^3 t2 {) z4 [) V W// Private members2 ~/ B4 G6 h% _7 H- L
private:
$ g4 Q& z0 Z F8 K# o+ t( q DWORD m_tLastEvent; // When the last event was received?
4 A0 h6 M: {8 ]/ P std::vector< DevicePointer > m_pDevices;! D- y" |1 [$ j5 Y9 F
std::vector< ServicePointer > m_pServices;- s/ ~3 e' L: W y) x
FinderPointer m_pDeviceFinder;
/ D; f7 w4 [9 R DeviceFinderCallback m_pDeviceFinderCallback;
/ k- B3 z$ R3 D ServiceCallback m_pServiceCallback;9 g: m. e$ P6 g: l3 x8 q) M d! r
: I# |7 P+ T: K6 @* g8 c: A
, s$ f9 z0 h, v2 [ LONG m_nAsyncFindHandle;4 E! x- o+ e0 U# e' i, D" G* q/ E
bool m_bCOM;1 P1 s8 b& |! u1 R
bool m_bPortIsFree;: r- L' q/ K) f% e v6 f
CString m_sLocalIP;
% M* K/ H" D* a* W: L+ P5 ~) [ CString m_sExternalIP;- t: L6 x& Y, [% W
bool m_bADSL; // Is the device ADSL? n" X/ w9 O+ t. f1 O, i' A& V1 d
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
7 g+ D7 h/ w x5 Q$ E. A bool m_bInited;
/ C8 Z& b$ }4 L# j/ u bool m_bAsyncFindRunning;
, b a9 i! ?2 |9 }, E5 R. w HMODULE m_hADVAPI32_DLL;
. ?. j/ S j$ A HMODULE m_hIPHLPAPI_DLL;( ?* t" A) R& q( M, q
bool m_bSecondTry;
. W7 Q0 ]3 A9 D% t bool m_bServiceStartedByEmule;
2 h" T# \( i3 h7 { bool m_bDisableWANIPSetup;
! @) d* v/ E1 P6 B6 c4 d2 C& b2 p bool m_bDisableWANPPPSetup;- j+ f7 t& R7 \! L4 X& V6 i
u1 ], M& v7 l, W. t/ Q% X
7 o# _& S7 V- {" L# ]" K* [};3 s/ X+ i5 i! G6 d; i: s, F6 B m5 P
2 {7 F- t" l. m6 s
: ]4 F5 j/ g& K4 {// DeviceFinder Callback
u1 k5 [3 ]" B$ Q8 u! mclass CDeviceFinderCallback
# d! P( |. N, V- T2 K5 T6 S/ n) p : public IUPnPDeviceFinderCallback
' g: E7 @0 M6 Z$ [{( _* d4 T" J+ v4 V4 f2 \
public:3 U* I' E+ L( k+ V1 z
CDeviceFinderCallback(CUPnPImplWinServ& instance)
. c, t- k' r( n" P( ^. B : m_instance( instance )) j8 D1 H) }, _( i( t% }
{ m_lRefCount = 0; }
* ?; W# f1 e+ k7 |7 i4 V% \" h
" J# Z4 T, r6 A
2 b+ r1 q3 Q' h2 } STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);% V; W( c& p$ t2 m- g1 F9 }
STDMETHODIMP_(ULONG) AddRef();+ D- [4 t# n! u5 p! O
STDMETHODIMP_(ULONG) Release();
0 U: I3 B8 r0 a) Z& ~$ T+ k
) l2 Q* |' ~( H% X$ o
2 g) ^5 ]# r N( C' m! b( T3 t// implementation
" [6 r& r @3 A' ^3 z7 Vprivate: ]/ @/ V) ?! |' a" T4 _
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);: Z' L. E ]1 b) D" d% i/ d
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
( P$ l/ ], l' z) d0 D HRESULT __stdcall SearchComplete(LONG nFindData);
s3 k: t2 _! w) G# f9 T0 z! K
" t2 ~# l& V% T0 S0 j1 @; y+ g, L' M$ _9 o
private:
3 H6 ?% n i* s CUPnPImplWinServ& m_instance;
& Y5 S/ V- P7 P% ] u6 W3 Q LONG m_lRefCount;
2 x! U1 p9 _% `1 f6 x7 S};
' ]) u7 Q2 a+ } F' d# Y! p; O) q/ b# ^& V! K4 D
5 {# Y) f. a, G2 @
// Service Callback
: w" A% i2 _7 I9 Iclass CServiceCallback
8 s1 f c6 L% M' e ^ : public IUPnPServiceCallback0 b# F$ A7 n# ?1 m8 `$ @
{
, {% P: x! @) X4 C- mpublic:$ L$ f+ q& T9 G7 z$ s. z
CServiceCallback(CUPnPImplWinServ& instance)
2 d! K3 t6 H/ U* ?; ^: g4 y : m_instance( instance )* O# W8 u8 j. k4 t' @$ U
{ m_lRefCount = 0; }' D/ v0 A5 W& L, |- d5 P: F
. `3 n+ z& i' W' n% ~! I# R7 s STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);# g1 T( I8 Q6 y2 C: }
STDMETHODIMP_(ULONG) AddRef();. R0 B" Z" T/ Y6 w' c6 ~
STDMETHODIMP_(ULONG) Release();
: j' l7 l5 X" @! r! O# |# ?0 @5 [9 [ w1 k
2 m# c( A7 U" S
// implementation
. j2 h+ @8 b$ V( wprivate:3 ?' ~7 P1 ]& c, H. J
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);8 f0 S5 s5 q, n, M# B" p
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);( i! h# `- K/ V% M. V0 r
5 z4 S0 O/ Z- H U3 R- F
& l8 V; K) c3 C8 M) ~private:$ C+ r" V2 J, q4 T7 S+ l
CUPnPImplWinServ& m_instance;
' ]; S# K& o H$ z( | H3 d LONG m_lRefCount;' B) T. o' u6 ?& e
};
* \- b# ^) H O# |) S$ U$ B4 J( x y! b4 Q
; s+ c$ O& E3 e/////////////////////////////////////////////////4 D( h' N; A; T
2 d5 ^# d! w; f: |
! O3 |! y* Q" P) h6 c: r4 y使用时只需要使用抽象类的接口。5 }4 o7 T* k/ @/ E5 M; S
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
% q1 i- s2 H; i. k9 DCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
- e! B" x5 j# Q, X' H. fCUPnPImpl::StopAsyncFind停止设备查找.6 a- d# ?- m6 E" ^
CUPnPImpl::DeletePorts删除端口映射. |
|