|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
' J+ N2 v# ~: R4 }- `' B) R9 K
4 Z$ A, Q* K' L: K% e9 O) ~& E1 B/ F$ `0 [( Z7 `: ?% P& o0 g2 V
///////////////////////////////////////////
4 o" S% z4 a+ i, K; ^' G; p/ z//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
$ K/ ~* |2 A* }/ m" `! u- W ?/ }: \% H& Y& U
3 _- q$ [; d2 m2 g
#pragma once+ o. w9 L7 a; }# u6 J
#include <exception>$ ]7 Y6 `# S2 a: B8 d& t! d# Q
7 P4 ]& w2 }% w' S3 u8 u. F, k) X
* y; O* y" u: a2 M2 e5 ? enum TRISTATE{
6 p. z4 J! a7 o" P, U TRIS_FALSE,1 A3 x- k. t' n, T, o* J
TRIS_UNKNOWN,
& u# r" l% o: f TRIS_TRUE" I; @6 v$ Z9 h$ E
};
+ M3 G- ^, N5 T6 B3 n5 z+ X+ c
% l" w3 H7 ?- p; cenum UPNP_IMPLEMENTATION{
9 B- A1 H4 c& q% @. ^9 o UPNP_IMPL_WINDOWSERVICE = 0,1 V6 W3 N' b: s
UPNP_IMPL_MINIUPNPLIB,* c3 H' `8 |" W0 V( z
UPNP_IMPL_NONE /*last*/
8 l% M; e, K! d' J};
6 W1 I' A6 E* j( ~8 d% D. U @
6 |3 w% X i, L P- G) q0 {5 C& B0 O- U: f: {- J# h
9 H$ ~; h& G0 r. V0 J# ~
5 p* s9 @8 P8 I* g+ Yclass CUPnPImpl
( I' h: S8 h" O+ |- ?" Q( e{, o# h6 A' k5 a( q
public:
- w4 O* ^! B9 Q; Y CUPnPImpl();: ]# R) N! W$ \5 X) d- y4 p$ k
virtual ~CUPnPImpl();% W! Q3 |& q& f+ G6 w
struct UPnPError : std::exception {};/ L# X$ r9 A5 O0 v0 A& _. m6 s
enum {
! X% m5 h( H+ {$ O' }# P/ v UPNP_OK,
' l- O# q' o5 J UPNP_FAILED," Y7 n# D9 R/ K/ S' I
UPNP_TIMEOUT# j2 L- h3 T& R! F z4 N) Y
};8 l2 q1 v$ M' O6 h( a, f
4 f" a2 D& x: V
6 `: \$ y1 h/ b1 v9 L virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
% ]9 G) ~. s: ]7 a5 n8 f virtual bool CheckAndRefresh() = 0;
( @3 X# r* ]( J virtual void StopAsyncFind() = 0;
$ ^+ k8 H1 @8 F. i+ I% p1 X0 A virtual void DeletePorts() = 0;
S8 ^& y2 V; m7 X% P virtual bool IsReady() = 0;
+ @5 \: I- f3 I& M virtual int GetImplementationID() = 0; _) ]) [ g5 u5 Q
8 M/ C9 |, l& f, D1 B; T# a void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping, C3 _% _7 [0 Q" }
8 p" Q0 U" Y1 _6 E! ^, z/ m
2 Q1 x. G# a( R6 D5 Y, R
void SetMessageOnResult(HWND hWindow, UINT nMessageID); N K. D% N' r4 E* t
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }& E) w& D3 }! t; f
uint16 GetUsedTCPPort() { return m_nTCPPort; }
# Q* L" k& k# V; u& `2 { uint16 GetUsedUDPPort() { return m_nUDPPort; }
- X; V3 q& s. J6 U( `3 R
, ]# \, ]( i% O& y! L. ^$ _( `4 e7 Q. @* e6 l
// Implementation
]9 L' x# b: D8 b; Z$ }; Hprotected:
, `% N: i7 J& v: {9 h o volatile TRISTATE m_bUPnPPortsForwarded;
6 L$ T6 ]+ d+ P& J1 I void SendResultMessage();- |0 H8 Z# o" f# q* Q
uint16 m_nUDPPort;
: j4 `% c* R. {' c$ @ uint16 m_nTCPPort;
. g* J3 I u2 D/ w& ]+ i uint16 m_nTCPWebPort;
. y0 T/ o/ r1 Y bool m_bCheckAndRefresh;$ V+ o2 w) E" f& s
2 V. v/ [0 T9 _0 r. G1 t4 P) D( y
' T. U. ]( L, K% o! ]- }% zprivate:
1 d2 C5 S7 z+ v: [5 O HWND m_hResultMessageWindow;- Z% X! E3 @& T/ ?4 M
UINT m_nResultMessageID;% K- C4 }0 @1 [" f7 z- A- i& g
+ `0 d: f" I+ V& [* N0 e# X6 U8 r, ]4 N' p& t) c$ ` ~; |9 h' |1 l$ K
};4 o7 n7 ?+ [* W, n) N3 L# o' ^7 T
, g$ E6 P7 y7 |5 ?
" j6 @5 ^, h$ b/ }% T
// Dummy Implementation to be used when no other implementation is available# s' x4 C- ^- i2 k5 g' y6 Q1 N! u
class CUPnPImplNone: public CUPnPImpl
9 b+ C5 N! A* x- N3 C8 |{
& e+ c( R' k5 D: C( epublic:
3 t( ~. ?) G2 L7 s/ ]' g, p7 k virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
: e* H- F- f% y; p' a) x6 r virtual bool CheckAndRefresh() { return false; }
7 s2 J/ b2 w& u2 ?* v7 U" x virtual void StopAsyncFind() { }0 A s! b" |% g% F# v+ c& I1 }
virtual void DeletePorts() { }
$ N$ H; n) \8 A( U5 M- g virtual bool IsReady() { return false; }. }' m* d. [$ Q' t
virtual int GetImplementationID() { return UPNP_IMPL_NONE; } L9 X$ a: I& x7 Z4 s. G8 p
};- w, ?; v+ `& c2 {
6 C9 z! z& l) d1 C3 @
; C5 r, [, f) l9 Y
/////////////////////////////////////0 M$ b6 V0 S3 y. I% Z7 ]
//下面是使用windows操作系统自带的UPNP功能的子类) S9 d% h; H0 } T# O% i
1 q1 u8 s; }& I7 o
& \0 [! F0 Y7 Y x/ m#pragma once# ]$ C, f5 A$ |8 N9 z
#pragma warning( disable: 4355 )" ?2 q8 V; u+ t4 M
- y9 A, T1 w8 b" z" G
$ U/ F& N' D# t! Y1 b# j7 z#include "UPnPImpl.h"
- Y$ {) ?0 s$ I9 D- ~# z; ?. g5 J6 w#include <upnp.h>; [9 q( o( a7 S- X1 M" H
#include <iphlpapi.h>+ ?2 J( O* O5 v2 [3 |
#include <comdef.h>
$ K# w/ ?: o2 I ^/ ]#include <winsvc.h>
* M0 E" W3 }- O- B. D7 u: i
- ^+ {' {4 {! X* J, r1 @- J, u) D4 ^% o& T _, J
#include <vector>3 k1 s Y1 ?: o' [
#include <exception>
% e# G( x" v7 w6 K* d#include <functional>
8 P3 Q1 H. y( A$ y7 }& \ ^1 |' m G& |6 M/ _6 U/ F4 I2 L
0 t5 r3 e3 i: h1 v8 Q" j4 y) y
" _ O6 t) M: @' r1 y0 W& {+ i+ L+ H( X' [
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;2 l7 {! R4 o& r3 S6 |8 G
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
" T" c0 G- ]$ \! `5 b& btypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;; `8 G& E1 R7 ]2 @+ R# Z* r
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;& ]: }8 c; x* H, Y( o* `, U
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;: j/ i9 d$ M9 _
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;* D V+ I+ {, t! ^' P0 v. c
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
8 V/ k8 {, q* u+ O z
% H4 o0 |9 @: ^ n' p- ^9 e& X8 X! N/ `, m$ I5 A$ ?5 x
typedef DWORD (WINAPI* TGetBestInterface) (
5 c$ o! x8 F7 t% ~ IPAddr dwDestAddr,
% O' @& h f$ E# s& ~ PDWORD pdwBestIfIndex
$ X( _) O+ n; C);: B Y/ @7 B6 w8 x
) S3 t* I" _+ \( ]% }* o
, s8 v6 X3 z" J& qtypedef DWORD (WINAPI* TGetIpAddrTable) (
# g) `7 D0 f0 v8 a/ f+ N8 y PMIB_IPADDRTABLE pIpAddrTable,
, v/ H1 E% e+ x: P8 ] PULONG pdwSize, \, }2 v4 M, I1 d. i
BOOL bOrder
; x: L I' p8 p& a( Z. ]. X9 R( o);
* w$ A- X/ X; V! T: t. Y0 ^, i
) v+ W$ m8 H3 Y) ?- W. t3 |' e) ?" ^" `, L% |. D O
typedef DWORD (WINAPI* TGetIfEntry) (
@ x; }' B9 G2 e; k8 e PMIB_IFROW pIfRow
, Q# E3 l' d8 D. w; @);8 {/ z. W0 y, d6 x; ? g& J
0 \& _/ n) F3 c& [# h* M% ~
0 y/ K* E% t# o; ?- v: `6 z
CString translateUPnPResult(HRESULT hr);
]* M- x: \6 a7 y+ XHRESULT UPnPMessage(HRESULT hr);
: t7 X; F# i9 S1 b4 ~
% l# ^) a5 u* s5 D+ [$ N# O1 ~( |8 j `1 c( B
class CUPnPImplWinServ: public CUPnPImpl D5 `1 T* _# m2 f# d
{
/ L6 P9 Z, p% y1 B& O# O; p friend class CDeviceFinderCallback;" P0 R- O. }* O
friend class CServiceCallback;
4 K( J* @: I- S3 q( @3 R, P2 p y// Construction
- ^& q. b6 l$ ^& `1 c; @8 p% \3 Tpublic:! G$ L1 x5 L/ s4 c& ?
virtual ~CUPnPImplWinServ();6 o6 U e7 G- z) C2 a' @
CUPnPImplWinServ();: K# y; Y( r! N& b1 b
7 l: q: o. M$ X) v% F7 ?% ~" W0 `5 f6 V: R
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
, {/ G4 o7 S# x( K virtual void StopAsyncFind();
( X7 W, Y5 T2 m virtual void DeletePorts();
. d3 |; _; L2 R7 a" C! c virtual bool IsReady();; u3 j. y l" h0 I! s4 V# r9 E
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
% s. N$ Y) t- F# C( q& n0 I" t( T: H* q9 ~. h( a; |
7 M Q2 \& ?% H9 r0 w, K // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
. R, h& ]: u: z T4 i9 ?: @ // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
+ H, n6 k# r* O9 S2 A. M' l) r virtual bool CheckAndRefresh() { return false; };, M7 a: A, O+ J/ I( K
. F& T2 J) Q& v+ L( B/ D! z+ V
- ]1 G$ k; L6 Zprotected:8 _% o& l R, V
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
) W- B( B! ~- R2 d# O. r void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);" V) i0 a0 c9 e2 j6 e3 K: O, l
void RemoveDevice(CComBSTR bsUDN);
6 G7 L j9 T; y5 Y- n- u: B3 d0 f bool OnSearchComplete();
# s- L( i# ^) Y3 G6 z void Init();8 {% B! ]8 @4 j( ]6 G4 p8 c
4 a0 V& }* P, I4 a: b5 a% X+ x! Y# \" z
inline bool IsAsyncFindRunning()
( x' `' K4 A/ k7 I; C; }, d {: ~$ t' l/ w+ ]& t0 X
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
" D0 `* k8 \$ _3 m0 L8 x/ n {# J- ^; M" f- `/ f0 ?8 n _
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
* c7 u6 N7 ~2 V) N m_bAsyncFindRunning = false;
/ Y4 z, [# L/ W$ ^7 t0 K3 { }) n: O* }7 i6 \/ P% n+ N1 r
MSG msg;* _2 ~2 V( f+ c4 F. F* d
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
% A' |' ^9 _* H: d8 s {
* g8 P; d5 Y* w* s5 Z6 m* N+ l2 y2 O TranslateMessage( &msg );5 T! d9 O. E1 H v/ p% y
DispatchMessage( &msg );' w1 g0 c8 O. F7 g* Y- N3 J, |
}
* ^. x; b+ a! p" V0 P9 z return m_bAsyncFindRunning;$ c0 F4 Z- U5 v: X
}, n8 A: y% C' Y, W3 |3 r
6 {& S# b8 \0 M5 ~: u
: S! s5 o4 {' [+ s# b4 E' [ TRISTATE m_bUPnPDeviceConnected;
! X1 R- z3 H6 R" g- N/ Q: y
( I; n, H! n* ?9 x f+ i2 C
9 ^" X' Z6 E. j% o// Implementation
, i, g7 p# t4 x5 d // API functions
# v: c' I: j! D! ^ A- u$ \, b4 D SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
) o. [7 O) M C, _7 m SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);8 \" A$ e: ?/ Q/ n7 W9 D0 Z
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
3 F' p9 T7 ]# y+ P% x$ z# K) r1 D5 E BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);# G% X, G% w$ c8 C- q0 I& T
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);2 x1 S$ W/ W, c5 R
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
. P! ^" ~2 N7 @0 Y, n
7 q- k" p' |' P1 B0 U% J: Z" F$ t/ K, ?* v5 N8 t* e, L
TGetBestInterface m_pfGetBestInterface;7 Q" K% T' Z$ ]: R3 a( |
TGetIpAddrTable m_pfGetIpAddrTable;2 E# q: c% `0 S4 W" {
TGetIfEntry m_pfGetIfEntry;4 |* O B. x9 S$ q6 q
" O8 ^" V: Z) i5 U5 c
8 g' X8 t+ E3 z+ ? static FinderPointer CreateFinderInstance();
" B8 ^# ?5 m0 H5 A9 ?) T' I6 y1 L struct FindDevice : std::unary_function< DevicePointer, bool >
& g, |: p1 |* y' o! J" T {
k c$ ^% y/ A2 X' h FindDevice(const CComBSTR& udn) : m_udn( udn ) {}6 ]4 R4 o0 y7 Z
result_type operator()(argument_type device) const
# X$ d- @6 W1 i) E {2 R3 X3 T8 e* `. B: `, n+ Y- g% C( G
CComBSTR deviceName;5 B$ y& `" t; v! g2 R5 K
HRESULT hr = device->get_UniqueDeviceName( &deviceName );5 e, l# |8 M: v j
; i8 n. U$ T6 [* n. A( I
/ b+ ~, V2 C3 p( \& m if ( FAILED( hr ) )
/ f+ ^# ]8 ^, E4 U" }6 u& n return UPnPMessage( hr ), false;7 }0 T4 `& T/ g2 e* i) U5 Z- L$ }
! y. x s( o/ G% f: N5 ~
1 V& F+ z1 S& O% k4 v8 _7 I return wcscmp( deviceName.m_str, m_udn ) == 0;% t) F. W$ T# M8 b- c2 ^6 I
}
+ T4 D6 Q( f3 r$ d CComBSTR m_udn;
6 b. n: R/ w \4 Y* a* S$ M };/ l0 h) q8 ^% p/ C
$ F& L9 y+ P- C: O9 ?# d! ?
void ProcessAsyncFind(CComBSTR bsSearchType);
G& F8 w4 H4 o0 t, l HRESULT GetDeviceServices(DevicePointer pDevice);
; A9 M% ~6 D$ K {+ a9 o( T void StartPortMapping();6 N9 j/ ^! [& b# V. m
HRESULT MapPort(const ServicePointer& service);
5 q4 L4 C: P8 o void DeleteExistingPortMappings(ServicePointer pService);
* K. r7 C" ], R+ L# K& n" \; W void CreatePortMappings(ServicePointer pService);7 {8 Z' _% [0 U
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);; s; l: v' s+ T( H) P3 Y
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 9 l( Z% L2 Q0 e5 {! h% r
LPCTSTR pszInArgString, CString& strResult);" X% A9 {8 I& F9 O3 u
void StopUPnPService();+ ?& L! \. L. r& ?: P
5 K: O+ L* G6 w6 p. s8 R) P& R6 q5 u! I, K/ P! q4 z* o1 w
// Utility functions7 e) P3 F6 g0 p: d f
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);! I' j' n1 ^9 I( y {& _
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);& Q/ v+ f8 c( P7 H& q5 |+ x
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
6 X3 A( q; |" N+ p7 c7 y4 R void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);' p2 B, n. k! `* {6 [/ t R
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);- l& \+ X: G/ f
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);. {& ^4 G) Q* D: H% y
CString GetLocalRoutableIP(ServicePointer pService);
. Z! ~3 r4 | A9 x4 x5 ~4 p! s& r$ x4 Z6 P9 n
: { n' g) y7 Y) d5 P4 Q: g: {
// Private members! w8 x- e: M8 n5 R
private:
& d, }! J _; c3 r4 s3 e5 h9 O) J DWORD m_tLastEvent; // When the last event was received?
! C, e+ k; a9 a9 `! j std::vector< DevicePointer > m_pDevices;
# I3 D, G6 ~& V' K std::vector< ServicePointer > m_pServices;
9 x. i+ ~6 y! t J5 N3 m FinderPointer m_pDeviceFinder;1 i- m& H" U, V- i' N: _+ X% j" t
DeviceFinderCallback m_pDeviceFinderCallback;9 E0 W1 F; v4 T2 S8 l5 `$ A
ServiceCallback m_pServiceCallback;
& Z+ k/ z) H5 d, n3 S) s
7 Z U8 g" m6 Z( l1 H" t& w0 q: B7 M- D' p, ^- y7 t' E7 }
LONG m_nAsyncFindHandle;
# m, A4 {$ F! i$ L# Q! D! Y9 f( S/ x bool m_bCOM;& n2 F- Y/ {7 K0 Z3 {
bool m_bPortIsFree;2 J2 r( |; w/ c% _5 e3 u( z# x
CString m_sLocalIP;/ V1 g: o" k* J
CString m_sExternalIP;
+ ~$ y4 j j: F bool m_bADSL; // Is the device ADSL?1 b+ f Q9 w# c3 d8 r1 T
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
4 _' {" X* a# }4 F$ o! R" X& K bool m_bInited; `- I& [: _1 O8 o7 y, n
bool m_bAsyncFindRunning;% t* O4 y* ?/ x/ t! s6 B
HMODULE m_hADVAPI32_DLL;6 |9 a- `! q+ z% I$ I7 ]: u: k0 D
HMODULE m_hIPHLPAPI_DLL;; M* t) x% p8 r& V: \8 F* e: c
bool m_bSecondTry;8 Y1 _0 o' G7 U+ Q7 ~. D! S3 ^
bool m_bServiceStartedByEmule;
! r5 Q& U& s4 d8 J, N bool m_bDisableWANIPSetup;
. m; L0 g9 [" F bool m_bDisableWANPPPSetup;! S) P- d9 D9 c2 }- h' L
' o% G6 R7 Z# b' N! k3 j+ G: f: c& U# B/ `. F3 x& r! l
};
$ G% A! N) Q( C* |3 t
5 `4 S8 ?# [! d+ [3 n! g5 Z. I
3 p" x$ F( `4 M( _! d// DeviceFinder Callback
6 M! f- ?6 N- sclass CDeviceFinderCallback
6 B0 {2 N& t# @$ I2 @ : public IUPnPDeviceFinderCallback
, L: f+ z) F% L; R U* \{4 c$ c4 G. I. j* I0 ]3 |
public:; \* s1 v! k) o7 ]8 \
CDeviceFinderCallback(CUPnPImplWinServ& instance)
" }2 u4 V7 C) i! h0 @ : m_instance( instance )
" x% J# t: r: S# p0 j8 A { m_lRefCount = 0; }/ X) L' s; f9 u" A: `$ P; w
: _! `( h4 k* t4 R+ V
8 t5 t! j& I' |0 i4 h2 R( ~7 o STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);! r+ X! g) L% ^7 Z B4 w
STDMETHODIMP_(ULONG) AddRef();( ?9 d0 E+ x1 K3 j" O- e3 E
STDMETHODIMP_(ULONG) Release();
2 ]7 T) e$ s# B1 B6 O+ s" H' P3 Z
! T$ U& W0 r+ L& C
// implementation
# k- d1 ?: w2 Q- z$ ^( B+ _ Oprivate: ^, S0 ]4 j$ i, a
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);0 ~! A1 T# _- I6 Q0 k6 N& q. o0 n; V0 S
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
3 z- J, P6 T4 t4 T; R# l1 B+ @: B HRESULT __stdcall SearchComplete(LONG nFindData);6 o8 H% V9 ^% I7 Q
5 m( B! |! g: o7 ^
- G3 ~! K3 K" W, sprivate:% H4 A. P l$ K/ @3 Z+ J
CUPnPImplWinServ& m_instance;9 }* V! T! x6 a& C
LONG m_lRefCount;
; r# S" i6 f8 v: z2 W) ]" ~};) q# M4 E5 x4 w. ]. G" X
9 S( c/ E- \9 I# {% k
# r' J9 ]2 }, ~; E) T+ G4 S// Service Callback
& u# I& g; D$ t) l9 hclass CServiceCallback
6 {3 v! i E& V+ A9 Z : public IUPnPServiceCallback1 [7 p- e6 K+ H6 i j4 L
{1 j3 b* a1 K7 x! P
public:# q/ L' ~* N! W, g/ [& L
CServiceCallback(CUPnPImplWinServ& instance), p6 f- ]5 l& p$ a
: m_instance( instance )
6 m& w9 z( |9 Z1 ]6 i, q$ L% A9 q" a- B { m_lRefCount = 0; }+ m/ j, J2 P4 D6 r2 b
% N) _' p. ]$ e' ]9 J STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);* ? @) g7 a: r+ u# |
STDMETHODIMP_(ULONG) AddRef();
2 {6 T' V# F, `, d3 u: b" g STDMETHODIMP_(ULONG) Release();5 ~3 K, g8 R% L
3 z4 E! Y2 v. X$ }9 R/ T
; b7 I1 a. ~5 M# I0 J! Q// implementation
' X$ G! X+ {% h* m$ c, bprivate:
9 Z$ e! H$ \: }; ]" @! Q8 N8 | HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);% R( |# a6 {# x' E
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);/ \7 H6 ~5 i6 J' J; M$ H& T
+ j# I6 e4 e* q
5 w( J. T8 F. h" ]private:
/ R( ]7 W* ^" k& H" K CUPnPImplWinServ& m_instance;
/ D# y9 s+ H/ e2 C/ D- [$ d0 L1 Z# ` LONG m_lRefCount;% \; \: m6 l8 u& M: Y) j& I R
};, G$ R% P7 E8 V3 w. m$ y' T; Q
1 q3 ]0 s6 D5 [" t N V* Q6 F$ i6 I5 Z) l7 I+ V
/////////////////////////////////////////////////
8 K1 ]( J+ ^" M D& U1 Y
* `5 r' z+ @5 v& ]% P
# y" u( a5 w5 ~. [1 Q使用时只需要使用抽象类的接口。
" n0 {8 }' y2 S6 Z k* CCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.
. W2 m4 ~* X ]' D8 R' ~: ]& kCUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
0 C" C, z% R/ T( p/ U" GCUPnPImpl::StopAsyncFind停止设备查找.: @ ]7 @2 \0 b: C; V1 C
CUPnPImpl::DeletePorts删除端口映射. |
|