|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,5 Y, ~. N, q4 _& U
9 e0 \" I4 A& P! q7 ]" |9 R$ E9 \ G
5 K: w0 f; o! G4 r2 s0 e+ r7 d- R+ n///////////////////////////////////////////0 D5 M; r( u( _. e9 p+ Q7 Z" z' I
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能./ ]: h( t. d. {5 e
( |+ G0 I7 a% D# Z/ j+ G4 M# c( G- D8 S) Z
- L- p( W- m9 P" I: ` e( B! h#pragma once
$ R; i: n% m5 l+ Q/ f* b2 \2 Q#include <exception># ^2 T# ~3 S9 L0 _' i
: Q5 H2 j5 f9 }% b5 ?6 {9 |; Q$ U4 O6 c
enum TRISTATE{: r8 V! a' b& h4 y9 l5 ?
TRIS_FALSE,
7 [) Q# o4 J1 z3 }0 R8 i TRIS_UNKNOWN,2 w; l' ^" E5 _ l/ W. ] x- o
TRIS_TRUE2 [* C+ F1 W2 ~5 C* R: Y
};
2 [+ v2 k, a, Q4 s( J4 }. a& ~& j" q8 s- p, z
/ ?8 K. ^; F h, c$ ~: F3 D" Tenum UPNP_IMPLEMENTATION{
6 _- k' ^6 C }3 E+ r ?: F; | UPNP_IMPL_WINDOWSERVICE = 0,
$ F0 a2 ^7 }# }% j* S4 ]. p UPNP_IMPL_MINIUPNPLIB,
: k. [- |; w7 P' x2 { UPNP_IMPL_NONE /*last*/
j* h! i1 X& T4 ?8 T: X0 b};% L" ?, O9 o2 u0 t
: R- V6 Z; X$ [6 u
$ n! ~( u% w7 y6 r5 e
3 v9 |: v2 ^4 v" [& n+ Z) l3 `* I. ]4 p; ]$ a) T
class CUPnPImpl
8 u1 d$ y- X9 Z A- Z" ^( Y{
+ ?0 r0 v( R1 ]) c, Dpublic:7 {. [, {. K' e
CUPnPImpl();
2 m$ k+ O- O6 r; |6 ? virtual ~CUPnPImpl();
( D8 P. {$ Y N2 e, l, ? struct UPnPError : std::exception {};
& L. d' j* j, @% `, G: x3 W enum {
1 y: W" ?$ ~" X UPNP_OK,
t* j0 ~7 E% o UPNP_FAILED,/ j5 g! N: {) X' s3 i
UPNP_TIMEOUT; F7 _4 I; E2 k# Z @- U
};
+ ^8 j2 |$ }: L- L2 [5 M9 M4 Z" J. H0 P% N6 |; u4 H: Q
9 ~) I; Y0 x3 u) E7 Q7 ^ virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;1 [, C f/ u- i* ^0 E
virtual bool CheckAndRefresh() = 0;
) o7 v* J7 z- f7 \$ Z; U: K. L$ s( }/ c, v$ d virtual void StopAsyncFind() = 0;
) q5 K5 m1 t Z s: S A R* R& v virtual void DeletePorts() = 0;
" R9 X( `/ ~( W3 A5 n4 b virtual bool IsReady() = 0;5 \5 k7 \- G* X: Z
virtual int GetImplementationID() = 0;
5 W! @" h/ r- O& J8 J7 f( u( h. u# v
. Z+ Y3 k. j5 m. U$ q% b void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping6 P/ ~, y, C, b: h& `
' q* V' _* j; h, b0 q+ A% [
, {4 S9 K- M6 }$ J) q5 A
void SetMessageOnResult(HWND hWindow, UINT nMessageID);; ]* E' I; M' b& |
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
+ @8 h% A9 Y2 n3 w uint16 GetUsedTCPPort() { return m_nTCPPort; }" r: P- `* w+ T
uint16 GetUsedUDPPort() { return m_nUDPPort; } : a7 e* V1 i1 G8 A9 l# x- P ?
9 Y! n1 z2 P: \9 V
& S! s( F" }, s- W$ D* |$ t0 m& _) u5 o// Implementation
, G$ l. }# f" oprotected: d( ?# ?+ V1 D! B1 ]5 x/ \/ `/ e- r
volatile TRISTATE m_bUPnPPortsForwarded;) x& p" Z3 U5 [6 n; g: l
void SendResultMessage();' S3 Z/ {" M% J
uint16 m_nUDPPort;
% `/ _# A8 D6 C: @1 h. W' a9 i uint16 m_nTCPPort;4 e. {" e1 w* ^6 \7 i
uint16 m_nTCPWebPort;
' O" L7 k( Y0 T- A9 T bool m_bCheckAndRefresh;3 w- P! k" x* A! G5 f5 M% |& E
# C! ^1 N5 z' T+ l" G5 [+ Q }% {7 j6 }, n; x
private:# }% B0 a$ @! m6 R8 X& O
HWND m_hResultMessageWindow;$ B- C% Q* w) f Z# O
UINT m_nResultMessageID;# V/ c- D! F3 R- Z
3 I1 D* C5 S) ^$ G' g% b. J
Y9 \( ?' l G- e
};
; Z, j( A% W/ t. R9 I, n
8 P" t3 N7 ?% X2 d. c0 X" i
: j" H) n7 K; {# y. w8 a9 Y// Dummy Implementation to be used when no other implementation is available
) E0 K* R- k. `; j* j N* Hclass CUPnPImplNone: public CUPnPImpl
3 x* q: f1 J$ _6 @# B4 [{
$ u4 ^) }5 v- R4 W, gpublic:& \7 O- O6 s8 A+ O
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }/ a9 s) ]- t: J# a
virtual bool CheckAndRefresh() { return false; }
( P, f7 N. w+ Z: N virtual void StopAsyncFind() { }
7 ~) P6 E9 ~4 {6 ~" N" I2 Y8 ? virtual void DeletePorts() { }
' h3 c. n+ X2 `( P: E virtual bool IsReady() { return false; }7 ], f! ^0 ^: Q: V# Q
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
8 {/ [ j# y8 ~0 r7 O. I};
1 N% Y2 g, ~7 w1 c
: B# u- N/ W8 _. k0 H: K0 q9 _4 N, ^
/////////////////////////////////////( f$ ^# T1 X4 q: |. h# Z
//下面是使用windows操作系统自带的UPNP功能的子类 N+ Q9 W# ^' H& d; W
) u# Z0 b7 O- g% G4 P% q
; e- R7 c) |; P) s5 O#pragma once
: Y! H* Q& j# P; f4 g$ A#pragma warning( disable: 4355 )
+ C ?& z7 z, E) C3 W) Y' u$ T: v0 B. n7 `8 X, ~' i" H
0 F4 g1 g9 C) r
#include "UPnPImpl.h"' V& Z1 ?) b& U
#include <upnp.h>
( d5 X1 Z8 r$ a( ~" j# V#include <iphlpapi.h>
4 \ ^2 J5 k- [2 A6 D#include <comdef.h>- b$ h/ W' V+ u! D
#include <winsvc.h>
, Q2 d0 F! r- Q! [; G8 c% j6 h% ?0 j- u. G% q# v f4 |$ [% v
) h% S Q. M/ C4 A; M. y; q- ~/ l#include <vector>
3 o; g7 P, Y5 N0 [# @#include <exception>1 R7 [9 E* M4 j3 o0 t3 L
#include <functional>
; l4 L3 V2 @6 R0 D, p5 n' Y' H( Q1 Y1 x; F* G& Y' V8 t
: l0 o7 {# O- o7 y4 F! A2 j
. c( f- }; M7 h" b1 M1 B' [. w/ X+ i R; i! [, |: V
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;+ ^0 V3 y4 ` j- C j7 u8 j
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;7 b( {; G$ c% p: z
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;; B1 B( Z: i3 D$ [+ c& R$ a. s
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;( t6 f; I! B* Q- N5 p5 H6 e' p5 k% E
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
. G0 b5 b% ]( xtypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
/ z# x" W3 J+ s6 n0 f& V/ Stypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
5 s9 W$ n) j- M V) Q
) V+ p+ G$ Y1 r" a
% |2 x$ Q8 ]1 G+ c, r3 e5 otypedef DWORD (WINAPI* TGetBestInterface) (% O# }! x" t3 x/ @1 g' `
IPAddr dwDestAddr,, J1 g6 C* n. ?4 \2 b
PDWORD pdwBestIfIndex' o/ D% m( p0 y
);+ R! g. ?! `, |( ^
, \2 G" P; {9 X
- V7 A% G! k+ ^. U6 Y
typedef DWORD (WINAPI* TGetIpAddrTable) (
+ t2 H2 ]1 s/ R4 G+ L PMIB_IPADDRTABLE pIpAddrTable,
. ~7 G- ~* B5 P6 V# d$ `9 \ PULONG pdwSize,! F4 R' p# Q. O8 u6 r# w1 F" i3 v
BOOL bOrder
0 o1 X+ ]2 i1 h) F4 w1 Y* z" U);1 V; U' `; B$ T6 T
/ Q& z+ _" I& E4 J+ X' W& {; a$ f
typedef DWORD (WINAPI* TGetIfEntry) (* U, o+ L8 l0 b ~1 m
PMIB_IFROW pIfRow
6 P1 |1 p5 C9 t, X);
7 Y0 E/ Y6 O% o" `/ H- q D& u& h5 v2 l9 j0 |+ B; }6 i
$ O0 ~- }( L( G$ CCString translateUPnPResult(HRESULT hr);: F$ H7 Y, ^) {# R/ J, {
HRESULT UPnPMessage(HRESULT hr);
' }2 [% h( M+ `5 F" i c- u7 S# }. W- K+ T% y$ p# O: x4 z
8 G0 }7 O! I8 d4 S5 c8 W% Uclass CUPnPImplWinServ: public CUPnPImpl
! S; K6 F% n3 s4 ]1 H{
+ v" j( X0 |( S# A K/ W friend class CDeviceFinderCallback;
. y- U C% f! C# g; a% q/ f friend class CServiceCallback;" p; _; d2 d, B, ~- ]8 Z
// Construction7 G, z/ y" A9 b4 t
public:
: K6 x) U7 [; k- Z! B; G1 G( r virtual ~CUPnPImplWinServ();! [* W" R8 v- {6 \$ B3 E8 t$ P: h# u
CUPnPImplWinServ();
) z/ Z1 I. R8 ]2 z$ ]3 L
7 M; l* a* b0 M# z8 s$ |# y9 E. R! W; i5 S m
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
; @+ i* o! q0 X8 L6 h) Z virtual void StopAsyncFind();
( j4 |, F) l# ]0 R6 `# S5 J virtual void DeletePorts(); a" g, U+ T* w# X
virtual bool IsReady();! y- G1 t5 I/ F
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }% Y7 R1 S! U7 E$ `' p+ C' A0 z
N+ m( k6 U( u
+ E2 [7 q! L7 T3 P // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
1 F; s8 ?! |7 ` // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
2 O$ V6 x, {" i virtual bool CheckAndRefresh() { return false; };
" x( p% n/ F6 C; I5 ~. |/ u% f* x. X! F* u0 s% B/ H* s
, D" C; o9 Y1 x, ?2 wprotected:1 ?' y8 f/ g& J: j# R
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
. F1 u% [4 h) x3 f9 V* L9 e void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
! S! x: y4 W! H6 @1 C& J void RemoveDevice(CComBSTR bsUDN);
( B. b' s6 ^5 P$ W% u. V0 K bool OnSearchComplete();
$ `+ l/ c! R( _1 V5 w void Init();: |/ g/ r3 V# H: x( p/ P! p
( R3 _- e! s$ a) D2 q" ^/ T
6 p) [8 y/ t5 u/ T: A( h1 p inline bool IsAsyncFindRunning()
H) k' j+ N' x {
% O4 E) v: M/ N' A+ @1 ` if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
8 `7 Y/ d0 p; k$ [8 @ {
2 m! m& n# _/ [. T) c m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
9 x$ z' J! W1 O6 M$ M% q m_bAsyncFindRunning = false;' P1 s) ?$ Y3 s/ @1 W
}+ J {8 d. ?: n' [( C, [
MSG msg;
. f4 D& `6 }" _1 c [ while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )9 X: m5 W, ^' S# w# D
{- n7 _7 b" B, @# { _& j, x( S
TranslateMessage( &msg );
|) v% B2 }+ g DispatchMessage( &msg );5 `" u! ?& k) d! X! v1 D) ~9 }
}' o4 [1 e- j( h* F
return m_bAsyncFindRunning;
* t! L: U4 I2 w3 c5 c4 d0 [* B }7 J/ G+ i8 u0 {! j; @
2 Z# l" k+ x' J' Z+ \* i
7 j& d2 `3 g8 v, c" S) T- P TRISTATE m_bUPnPDeviceConnected;
/ M1 U/ C& |2 d, ]0 X; Y4 [) G* G5 L; U, s# \ c/ E. R3 o
! u; Y2 r) w! @ f+ z- U& C% U// Implementation# U6 I$ [, L# h. F' s4 v+ G
// API functions, Q9 z: P! p- K, u2 ?. d
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
7 d* j) L9 V! w, R T h SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);! t- B Q$ g( z L" ]9 z0 r
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);! A! h* x3 B" G0 n { e a
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);7 s; |3 i: d1 I5 M3 d6 V
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);* A5 T8 [' i* A$ t5 @8 ?
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
0 }/ h6 k: E$ M+ D7 _* [
) K+ f% B2 ^5 V5 a7 A( n$ V+ K
! i' N, B/ `8 a TGetBestInterface m_pfGetBestInterface;/ } b3 v/ Q0 I$ S8 L
TGetIpAddrTable m_pfGetIpAddrTable;) H8 Z @' \7 q# k, d2 o
TGetIfEntry m_pfGetIfEntry;
, }; q" o5 s- y+ X4 `
7 B& E0 k0 b$ ^# ~
0 z2 @( v# b& x: a9 y$ O! B static FinderPointer CreateFinderInstance();4 j3 w* ]; O8 Z( n
struct FindDevice : std::unary_function< DevicePointer, bool >
1 q8 Y! m5 i) |( c4 s {
/ C1 R q7 \6 n1 X: W* h2 T3 X2 Y! A FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
. C" W' z3 T8 D$ X1 `; \" Z result_type operator()(argument_type device) const
: s$ z8 Q2 f( o2 w {+ a) m6 o6 n8 U, ~
CComBSTR deviceName;8 v+ O: q* I8 R6 D& b1 M
HRESULT hr = device->get_UniqueDeviceName( &deviceName );; h. }( B9 z5 `% f% G
1 g4 r* f R( v2 _5 [9 i
% A* s1 A1 w! G if ( FAILED( hr ) )$ k8 A: _' D% V5 b
return UPnPMessage( hr ), false;
3 S8 B2 [3 F. k4 t7 k5 G2 ?) u# P- S) v! H
8 l2 R$ I7 _0 S return wcscmp( deviceName.m_str, m_udn ) == 0;
O- O& ^ X: ]7 ]9 | }! [" N5 o- S( Y) r$ C C
CComBSTR m_udn;! o7 b( u8 M' H, L0 g4 i
};
/ a9 O3 O6 T$ r " } F" w3 L1 B+ Z" M
void ProcessAsyncFind(CComBSTR bsSearchType);" x/ @ m/ ]% p/ j2 P: l
HRESULT GetDeviceServices(DevicePointer pDevice);& O; D- \( [- v/ H0 r' L: e3 B8 Z% A
void StartPortMapping();" d! F* V$ l7 W4 U+ V( z
HRESULT MapPort(const ServicePointer& service);
6 b# w; |& _& K; m void DeleteExistingPortMappings(ServicePointer pService);
0 B5 }$ D( _2 o# V+ { void CreatePortMappings(ServicePointer pService);# I! D9 x8 ^2 b1 \! h5 j
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);5 F+ t/ ^& Y( U: G6 x- {
HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
* N( u) p2 a3 G# U6 q LPCTSTR pszInArgString, CString& strResult);
' A% O* g: Z: S. A2 }8 B void StopUPnPService();
2 q6 o) ~' g; u% ?+ {1 [ y, C+ R U1 t5 Z$ A) A# K5 n
7 Q0 N6 g' P- J! ~ // Utility functions$ p6 r) @, H; u V+ { j% v: L
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
; e2 n0 l: Y& |5 i, ]( _- W INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
+ _, i8 U) g. p" q INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);8 ]) J$ z/ h- O+ r1 h, @# j; Y) _
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);: s4 c. {% O8 q4 `
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
; `# V* M5 w x% g9 E; v# H! Q) z HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
( c% l' a1 i! D, ~" N4 t* Q CString GetLocalRoutableIP(ServicePointer pService);
* B& Z% Y ^0 Y" V- S
. x- a f; u0 j9 e- X2 T) m
+ W3 F3 B5 ^1 u8 S$ X9 b8 }* W$ [// Private members2 C7 y" V8 S, t; Q0 v
private:
' U# g% ?; F1 t0 w3 t* [. S DWORD m_tLastEvent; // When the last event was received?" x- p+ q& P6 X
std::vector< DevicePointer > m_pDevices;. w! U9 H. I& ?7 g( e
std::vector< ServicePointer > m_pServices;
i3 b- _1 W- E( ~- f5 t FinderPointer m_pDeviceFinder;& \+ \7 J0 f# ?' j# E; f! @! V
DeviceFinderCallback m_pDeviceFinderCallback;8 s, |. h% F& u
ServiceCallback m_pServiceCallback;
* H& d+ h9 H9 X+ ^
0 c" M0 ~) D- m# m
- A: c4 X# }" m' g# ]( z LONG m_nAsyncFindHandle;" z. L( m% }$ i$ y" c& F E8 V% s
bool m_bCOM;
- _$ _/ K8 x: F1 T$ s1 j bool m_bPortIsFree;
: L$ ]4 F; V/ Y: H) P; b CString m_sLocalIP;8 E3 b- e. \7 p4 L& u7 m: |
CString m_sExternalIP;
- z/ F+ m/ p% y7 P) {* O, b bool m_bADSL; // Is the device ADSL?
# z& w q% u+ N( m2 ~, N bool m_ADSLFailed; // Did port mapping failed for the ADSL device?$ G/ h7 F4 Z7 X9 u. s! G
bool m_bInited;
5 Y |, Q- Q" |5 }) @( L bool m_bAsyncFindRunning;
6 _: B8 K/ X+ W+ J4 d& S2 f$ F6 i HMODULE m_hADVAPI32_DLL;
1 i+ q& K: n3 z* | HMODULE m_hIPHLPAPI_DLL;
2 ?; \: \/ [& j1 s4 g bool m_bSecondTry;
6 S3 [0 m% v. H5 ?1 \/ \ bool m_bServiceStartedByEmule;
7 z" F$ |! I8 h( _" d9 ~) D bool m_bDisableWANIPSetup;# }" M7 u+ j O& b9 @8 t) I
bool m_bDisableWANPPPSetup;
1 K2 a/ B) \9 L( k9 X; d9 G- E
2 X1 T7 O7 B+ ^( d) f7 m( }8 B) A3 T( p$ o% d$ }8 Y
};
0 U2 c7 G+ `! m; ?1 N5 O1 ?7 D- f9 [/ ^2 H& }) I+ A6 ^! n( G: a
8 k: L0 z6 H+ m
// DeviceFinder Callback" I. E7 Y2 E" A7 |
class CDeviceFinderCallback0 O x! _5 I. D6 W8 S
: public IUPnPDeviceFinderCallback
. m6 g1 j) D: C) l% H" O [{
/ R* \7 g3 n D" L: A0 Fpublic:# F' y6 E: q/ r. D- o
CDeviceFinderCallback(CUPnPImplWinServ& instance). \4 h4 Z' R; K |
: m_instance( instance )! q3 _2 R5 x+ _' i" G& V% f. a( v
{ m_lRefCount = 0; }
9 M: p7 h! F1 o V6 [9 ~. {# r( \0 R1 x# ]; x
; v0 W) R5 d0 P2 y% ^1 R
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
2 w8 N9 A5 i. l8 y% q, s STDMETHODIMP_(ULONG) AddRef();# e6 n- f& z! N/ c& H8 `: A
STDMETHODIMP_(ULONG) Release();
) C3 o7 D3 Q" B5 W8 O) _. ^
# f, S) L. F) B+ a* R* ~ g# e4 |' D3 C
// implementation
2 m6 l5 c5 i, H- b& ]private:8 W! Q; V: v1 q5 g' S# X
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);: c# O+ |9 {9 U; w% A. w1 B8 D
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
B* [2 A6 U: C! r' s7 t8 s HRESULT __stdcall SearchComplete(LONG nFindData);# V* H4 n7 A5 i& J9 u
. q/ {# p- @) z2 D
3 c! K1 M2 r" p0 h5 E- p$ Tprivate:: F: M3 h- _* Y/ }8 K @; K% W% p& u
CUPnPImplWinServ& m_instance;
9 G9 ^3 w( p$ M" W% d: D( Z, u6 r& w LONG m_lRefCount;
+ j3 x) s! [: X' \) ?7 l! H, o};. L5 w; S c8 Z
. l/ {# F0 f& o, ^1 V
: g& y0 c* Z! G5 Y6 g$ ]// Service Callback & _* I5 U' _( h
class CServiceCallback
7 S; L" w) i1 M7 C! V/ x+ l : public IUPnPServiceCallback9 [3 `8 z# `' b8 t5 c p$ G
{: B6 ]6 d% Y+ O
public:0 Z* W; h1 i3 H! \( W
CServiceCallback(CUPnPImplWinServ& instance)
. ?- R3 ?% M" p. a: x& C1 `' g : m_instance( instance ). d# J/ g7 o, g& F- L
{ m_lRefCount = 0; }
; b* F) t$ U4 F ( @# B( E1 u- P/ X
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);# l7 b2 G2 Z! t! `1 x* Q: y
STDMETHODIMP_(ULONG) AddRef();
( F+ K5 S! o8 y6 U STDMETHODIMP_(ULONG) Release();
/ F# Y! w3 m. @. _0 k3 `) o; T3 ^$ I8 R
9 l Y, }4 Z2 n6 h% B% o
// implementation
) c& ?- E" p; m: k0 Dprivate:! U8 b* \4 K- t \8 A c4 x: \
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
+ e3 i6 S: m, E( g, h& y HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
7 A% h- U6 \0 [5 Y
m9 q) U: ~- M: J/ @) T
' f! X i3 M# n* j! cprivate:
( e2 Y0 H; ~( K: Y$ d5 L* E% Y/ d' \" ` CUPnPImplWinServ& m_instance;
' @/ x- ?/ T; g' } LONG m_lRefCount;' n) Z3 Z& }3 a3 u0 V8 P* M
};
8 ]& c7 u0 g' J: |6 v
; |- Y9 a( G! C- j" j3 W, K ^3 M7 Z/ C2 T" c0 c# K8 ]8 p- o
/////////////////////////////////////////////////
" q8 _5 L9 E, J6 v$ U* n+ \4 P K8 E" [6 A* r8 N
* X. H2 A. G; ?$ |8 c3 J% I( H
使用时只需要使用抽象类的接口。
$ F2 ]" B+ d( s3 YCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
& {& g* \3 P: M" P* w/ v4 O* RCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
8 u$ v8 D( J" O& Z! hCUPnPImpl::StopAsyncFind停止设备查找.
! Q" _6 U4 U4 c0 m! ?! n; F2 f6 I- KCUPnPImpl::DeletePorts删除端口映射. |
|