|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule, }8 a" J) B+ f2 p% G9 w3 s& E8 e
( M0 J6 n( A3 r& [3 |. v& }" J
! |/ j7 n: j# H3 f6 n///////////////////////////////////////////! `) b: y+ J$ L# e! p
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.0 C8 O0 p- c7 p
# _. |' Z8 f4 E
4 L3 T7 b8 v3 B& b#pragma once
! N% V- x/ `; H2 b7 R#include <exception>
, h& P/ P( O- h T. {
V$ n/ s3 Y6 y5 }6 V
% h$ u) B/ {9 ^ enum TRISTATE{
2 }; X/ C* J) `: T8 `* x TRIS_FALSE,) l& K$ Y% O4 w6 d) O: X
TRIS_UNKNOWN,+ ^; e5 y. s1 ]* K) W- y
TRIS_TRUE: x" Q8 Q3 U3 \) D) a7 J
};
" a* e. }* C+ W& L7 g3 r2 R3 K3 E$ Z0 M
- h9 q/ V* n: ?
enum UPNP_IMPLEMENTATION{
! M. s1 c; v2 j3 ? UPNP_IMPL_WINDOWSERVICE = 0,
- F% ?- g; {3 J" ?2 E* [ UPNP_IMPL_MINIUPNPLIB,
) e& B. b2 `2 {; h# A: j UPNP_IMPL_NONE /*last*/1 v2 V6 X! a9 ?# ~7 \5 A# C
};2 E# W- @% s; r: P M
1 Q X9 w9 y' ^$ U; U
. p- x) H) ]) L. s8 d, F% i" R" ~0 L- W. H' [
2 R, u; D4 v- m) E2 f
class CUPnPImpl! ?: F( @! B. g+ c. o4 X7 h
{
# b: }+ T$ Z U- z$ x P# M0 N- _$ e- Ppublic:
( O8 l7 Z/ f1 r2 v' s, [! B CUPnPImpl();
) r) B* a. h( y. k c virtual ~CUPnPImpl();. ]' h5 u; V$ W% H
struct UPnPError : std::exception {};
: }' ?, G6 [/ ]7 V enum {1 \+ P( g; d M+ R% Q/ g. A
UPNP_OK, Q5 u2 A/ p. j [3 d/ n
UPNP_FAILED,
% N) _4 k# `0 Z- ?0 Q UPNP_TIMEOUT6 N2 T. J. _0 e9 n5 v8 ?
};
1 p, z7 w0 z- I5 Z- \2 S
; c- O; G, y# D7 ^; w4 e3 v4 N" A6 ]4 S+ ^5 G8 [
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
- F' c( J& j5 l) H$ R8 z virtual bool CheckAndRefresh() = 0;) Q; c- L" B( h$ Z
virtual void StopAsyncFind() = 0;) _' c% y& H7 f# y" L. T8 Q7 Q
virtual void DeletePorts() = 0;
! `1 R3 r, U$ @1 ]5 R virtual bool IsReady() = 0;
% p/ D- | G5 S9 o9 U5 z virtual int GetImplementationID() = 0;1 v4 W0 l% ^* u* R3 c
6 ~/ N- N' m6 s$ r' D; D n void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping
9 j: o6 e. ~$ L( y4 T# B& t& i! i# B7 H& R8 o+ I
! n5 H) U/ R! f7 n
void SetMessageOnResult(HWND hWindow, UINT nMessageID);4 T' G2 U- r0 p0 S
TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; } w9 S2 s2 i! T. T
uint16 GetUsedTCPPort() { return m_nTCPPort; }: T0 A+ }& G& ]! N; d
uint16 GetUsedUDPPort() { return m_nUDPPort; } / j4 H; J: v4 J5 j: W* }9 `
2 o- m+ t `/ J9 m! g2 `; X' x
+ q: [' k6 s" B// Implementation$ q0 U- n& h' X
protected:
# X( ?7 h2 O" l8 E volatile TRISTATE m_bUPnPPortsForwarded;# ^7 m# j6 Y ^: k A, a
void SendResultMessage();
4 w; Z6 T( n. D2 G0 _ uint16 m_nUDPPort;
5 d( }! }" ?1 n. q/ n. P, \ uint16 m_nTCPPort;
- W+ u5 x. E. b- P0 H* A6 K uint16 m_nTCPWebPort;
- T1 t; C x. }6 \, }# w bool m_bCheckAndRefresh;) m! h2 Q1 K7 n2 {
) ^- O/ `# S; W; x7 x- j$ L2 h
private:
1 Z" l l. M2 \- L4 L6 | HWND m_hResultMessageWindow;
) W4 ~& C0 p. H7 s9 q7 g$ E UINT m_nResultMessageID;
2 Q, ^ T/ i1 l1 {
4 s. v/ `2 `; n5 r3 q& ?/ @
( E4 `2 N5 I( _4 c7 Q' p7 V};( m+ L8 {2 Q" S( w. n" f
5 h. S2 |, i( B0 {6 N
4 m$ ~* l' ~ O8 w8 |8 I n4 o+ f
// Dummy Implementation to be used when no other implementation is available8 P, \0 @% h [6 `
class CUPnPImplNone: public CUPnPImpl
/ B3 {8 b" ?" A; O; T{& ^% ?- W/ }; c# `: _
public:1 s: [, N6 F& I& j' @3 j
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
* X d5 [) F2 @) S virtual bool CheckAndRefresh() { return false; }$ Y$ e4 J" T+ k/ p: B5 a
virtual void StopAsyncFind() { }' q5 ~8 k* w3 x7 ]; A
virtual void DeletePorts() { }
: k! C/ z: `# | virtual bool IsReady() { return false; }' k' ]& @( e* x1 l! P4 u- b
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
! E7 h6 N* [" ]" C) C' ], j};& Z2 W# {. x6 Q; O; O* Q+ Z- y, [
: N( Q1 H0 S# `" J- z" h. m6 F4 i
9 c# E1 r. I" e. _7 X
/////////////////////////////////////5 j* D# y/ J* q! b/ {0 I/ c; t0 C
//下面是使用windows操作系统自带的UPNP功能的子类7 @ _/ [2 c ^. B
- l! Z. s6 G. G% x4 {
( f; i" n7 S) r, _$ L; u
#pragma once6 q$ W4 k( q* o5 g9 m" O
#pragma warning( disable: 4355 )0 p) R+ p; Y$ Y; @4 m, E
* W/ r, m, r9 d! T0 C. [% O1 |
$ _8 G- L6 c& n& U7 ?, c" `#include "UPnPImpl.h"
) Z3 V% t( @/ }#include <upnp.h>; h6 ^# x; Y7 S/ `
#include <iphlpapi.h>( f9 H- m0 T9 M. B9 @5 Y; g
#include <comdef.h>0 ~0 x( L0 d* S5 J0 c# J/ S
#include <winsvc.h>
, B3 l4 I2 @* P4 s- R7 U* d9 T5 P- i% L5 W$ V z& G
; c8 }( }9 |1 T/ B* b#include <vector>/ [: [7 U+ ^! I! O; d2 @8 P% R8 t, m1 b
#include <exception>
+ H+ U A* n- H' R0 n#include <functional>
; o! i7 _, Y0 x' W6 \. W7 E2 W. Q" D" i- e3 F: O& V: T
3 t ^* J! z( e( `2 `
[: D: w J7 G8 H# H
+ _5 I" W1 X r& a7 ptypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;. Y/ y6 |# h( g( O; G* V! j
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
8 _9 V7 }8 J; j6 \( Itypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
2 D4 W4 l6 G; {' D M6 C3 H9 Otypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;* _, r7 X% E4 v+ ?2 T
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;
" V. W/ f7 i% Q4 ?" x* K6 ytypedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
D& x& k* G$ n$ g2 Ztypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;7 [1 T$ h3 O" z" t& G
" P! A! u4 s1 P
8 y& s8 U0 k$ h$ N& f0 E8 T# wtypedef DWORD (WINAPI* TGetBestInterface) (9 ~; G$ q9 Q' X: G" i' C
IPAddr dwDestAddr,/ Z; i/ m) g4 @/ B
PDWORD pdwBestIfIndex/ w# X3 U# E" S! |
);8 c( C6 y/ `* F6 F( r! C% [' ?9 \( x
3 \0 k- e8 j8 g% p9 Q& _
8 I$ s& }8 R. N2 w9 f; W1 ~" }
typedef DWORD (WINAPI* TGetIpAddrTable) (
5 `3 |8 ?, G6 r3 p PMIB_IPADDRTABLE pIpAddrTable,5 g' a* G5 f$ O9 i9 V8 q- h
PULONG pdwSize,7 g. G3 h2 v. g) J* n9 Y
BOOL bOrder1 n* a# m. e/ X" i; e
);
; @ [# @# f- M9 w: k0 b: x
6 t* t8 d, \0 B3 f$ g
9 ~3 M6 W5 P6 O% a, @5 stypedef DWORD (WINAPI* TGetIfEntry) (
7 O. R# v' v, b) v+ N- L PMIB_IFROW pIfRow
$ w" U4 ^& D/ |- a; F# C$ S& x# O+ w);. b0 Y3 W# h. u8 S& N
: g& c+ |# g; A, {' b, o$ L& m. j
# w' Y) C, E" hCString translateUPnPResult(HRESULT hr);
3 `0 |% N' v/ l6 {+ G b( U( v8 lHRESULT UPnPMessage(HRESULT hr);
& ~% @8 ~6 Q( t# J1 j6 w# E) [1 e1 h" i9 z K! \8 T; k9 q
+ C" ?, o0 R+ \& Y1 l0 R. B+ |class CUPnPImplWinServ: public CUPnPImpl
$ f9 J* j5 N G. y, ?+ y# n{
( Z5 _- U6 B2 M% Z5 s friend class CDeviceFinderCallback;4 u- [; W; i' f, v2 K% g% U
friend class CServiceCallback;% m9 u( C1 M: G( Y+ Z4 i$ u' `1 ]
// Construction
: @1 I$ O' u. J& D( N% j: Opublic:( b' ~7 M8 A+ y: T$ z
virtual ~CUPnPImplWinServ();4 E) f0 r, j" K1 k2 `( N
CUPnPImplWinServ();
, c. p0 b8 F% f% o. n* i3 n2 L/ n' Z* g! l" A4 r' R
# b: _* f9 C- R( C virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
& V( y+ [) u6 k4 O1 a3 j7 u virtual void StopAsyncFind();
! S1 d' z5 T; S virtual void DeletePorts();" ~8 R+ _1 [% p8 n1 B* {
virtual bool IsReady();/ U+ @% l) k# Q
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }( r* T& Z# f! x& A- P# P5 y
; N! N- t& J" h& t6 g: u
* [9 g1 k$ P) _* r( u; F // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)7 {# E2 A z% C0 N7 |
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later: u5 z+ V1 }0 F' n9 R& _
virtual bool CheckAndRefresh() { return false; };) J+ N9 n; K) p9 n# _7 R1 s
! E# C) a4 d5 C. Q/ ?( d6 z5 `' O9 @, j1 i1 Q% m; w( q! V8 j' ]
protected:9 x) A- e/ c6 o" w7 G
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
3 q b4 n) O. Y$ M, H5 Z: o* H' k5 D void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
, o4 A: C( A% j+ V5 M1 c8 } void RemoveDevice(CComBSTR bsUDN);
, L% `8 n! S& y; Z7 D: m, X$ m0 C bool OnSearchComplete();1 T1 `0 k7 X0 L% w" X
void Init();
" t; ?7 ~, c5 \4 s! e5 U( r& S& o; I, }" N: I& v' T1 O/ t5 T' B8 C
1 i& s+ D+ i3 Z
inline bool IsAsyncFindRunning() 2 P8 b" E' a: D$ o+ V, r8 ]! T" P
{* c7 `6 G: D3 [- `
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
6 O: |. e( [( _8 R {. ?/ r: d' L( C W) |5 q
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );" I& @) j& b& ~! g0 {
m_bAsyncFindRunning = false;, h8 }2 [9 _0 E2 e* m1 s, Q
}& A1 ^ a5 D/ C- j) H- Y0 [5 y. w* p
MSG msg;: r0 h' o, u: ^* J o* n
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
$ n! ?! j- M& h, } {
* S" Z; ~) o- W5 C* Q TranslateMessage( &msg );
1 a8 h. @9 c2 ]* Q; p7 K$ B DispatchMessage( &msg );5 [/ W* M* E: a0 O
} }7 K, x& }* ]5 \" @
return m_bAsyncFindRunning;# D0 {* M4 y2 V/ I+ n
}
3 F+ {3 Q2 ^0 `. `3 V2 O; c# {& c9 F/ z9 z
! j# E5 A# c2 V5 d9 H' X. X
TRISTATE m_bUPnPDeviceConnected;+ g) }0 u% F6 v4 b4 o+ Z
' x# I8 V- _, G0 a V" }! T
4 t# t- T+ x* x% h/ Q# y5 b5 p// Implementation. v# J' U- H; O4 r3 B
// API functions( V! X7 t/ v( }+ A( o/ W. N R
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);" f/ p- a9 ^& ` `
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
" d$ _: v0 c6 I BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);* I; e0 c7 Y5 l/ B3 t# t& Y, k
BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);2 u* _, q1 [; ?# S' k% |
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
: I+ U; m6 o- W$ q5 f+ M, l BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);# P) C* ~0 i+ D$ F( [( I4 R7 V
" z( A& A" r& ~
, ?; ]5 D& C) ~) m- R! C3 O) {. _1 e TGetBestInterface m_pfGetBestInterface;- p. T5 r5 @! ~3 @& ?9 @: c, x/ g
TGetIpAddrTable m_pfGetIpAddrTable;3 ]! B- u! T1 S! X) T5 e+ V
TGetIfEntry m_pfGetIfEntry;
0 K O' |3 w9 l i; x; D% j1 F4 w+ R# Z4 P- {7 v6 s' ~# F
. I) T& C T/ h; V! p/ z0 g static FinderPointer CreateFinderInstance();
- W2 c; [) Y! [ struct FindDevice : std::unary_function< DevicePointer, bool >! n0 Y% l5 ~7 e: A
{( I( ~4 Z8 B# V3 }' N
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}
5 p6 B6 p" d) V/ W0 g& n8 | result_type operator()(argument_type device) const4 x7 n0 D4 c7 i1 I7 l* V( y
{
- `. u0 V. n5 E" w2 N. k, [& E CComBSTR deviceName;' Z/ r# }( J, B. `+ U) F* ?( n
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
4 y) R- [& w) a, p( {9 P" k% M/ T* Y) I4 q
" C! g! U$ @4 Q; i5 b/ f( o if ( FAILED( hr ) )7 G3 E6 D! E4 V8 O$ O
return UPnPMessage( hr ), false;- l- A9 e: z/ a' ^5 x4 o) S$ k
/ A5 \1 u& a' V- h4 f
" o. C2 _# H; s! H6 F( ^ return wcscmp( deviceName.m_str, m_udn ) == 0;
) }, \. K( T3 G }
( G; B! V7 I6 r CComBSTR m_udn;+ g K, P8 F. L/ e5 j% z
};
2 I; J4 e2 u0 o) c1 a1 _% W% a
5 b- }, @! N* ]% h0 l; v7 }, b void ProcessAsyncFind(CComBSTR bsSearchType);, t$ I J6 i% k# x
HRESULT GetDeviceServices(DevicePointer pDevice);
0 m* Z3 a% w9 P& k, V G void StartPortMapping();
& u: ?1 k7 t) e# U6 N# G5 o HRESULT MapPort(const ServicePointer& service);2 O, H% q5 \: p; u3 M/ i
void DeleteExistingPortMappings(ServicePointer pService);
+ _" q1 X$ t/ y: D void CreatePortMappings(ServicePointer pService);
5 w9 @3 G Q. c Q- R HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);5 m6 ?3 x* V& l' |4 t
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 1 z; S, Z3 Q7 c R
LPCTSTR pszInArgString, CString& strResult);
: p6 X; P# G( n. w0 k4 D void StopUPnPService();
+ A/ t. S* l( ] @
1 ^; _ K# G- r! k/ V+ ?; F. e5 O3 ?+ j. c& Z& Q' D" \2 X$ S
// Utility functions5 V4 \/ H9 ~) R: D3 F, r
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);/ Y) y0 X5 v( v. t+ K
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);6 B; k: D3 c( a, R
INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);6 V: S" v. {2 U; b
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
+ C9 n1 d1 d# d1 |+ B8 u6 ` HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
# @. k7 x3 P# K) ] HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
8 M; q, d# U# k U7 D CString GetLocalRoutableIP(ServicePointer pService);
9 l+ l: C* v7 S$ N
" z* R7 X$ [9 ~! a- ~* D( Y
2 F4 S# _' N: O+ q* T// Private members9 z) u) H4 Q" Q7 g; {. @
private:' g! R- v* t4 s) Z6 p) |
DWORD m_tLastEvent; // When the last event was received?
4 {0 }# E! A" \9 _# Z, g0 |, [ std::vector< DevicePointer > m_pDevices;
. z3 Q3 S/ J, B. Y+ b9 f, C std::vector< ServicePointer > m_pServices;- V* }1 v0 G1 L' ?) s7 Z
FinderPointer m_pDeviceFinder;$ q% ]# G: M- A4 G) T
DeviceFinderCallback m_pDeviceFinderCallback;$ n1 L9 ]4 ], b+ e4 e2 M2 i9 ]
ServiceCallback m_pServiceCallback;
4 r' n" n) t( ? W, z( m# Z$ u# l6 D. t7 p
& @; c: Z x8 j" X. [
LONG m_nAsyncFindHandle;2 S6 j- D- n* K! e* Y
bool m_bCOM;
6 b- g8 g1 N% |. c7 T1 _" b& m bool m_bPortIsFree;
5 B/ V/ g" \1 j) c" w3 b0 ` CString m_sLocalIP;! {2 Y6 h4 W2 z+ r$ h. X
CString m_sExternalIP;
- P G$ j; |) n! I7 }: I bool m_bADSL; // Is the device ADSL?' [! o- t+ |8 u# _+ z5 w
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?0 Z/ U4 t& q1 i: o4 T/ g
bool m_bInited;
* r: y/ N) K1 n! z" G bool m_bAsyncFindRunning;
c q+ s/ K) `1 D5 _% |5 B. C HMODULE m_hADVAPI32_DLL;
; }. \; C7 F! X; N HMODULE m_hIPHLPAPI_DLL;
( \. O. m O/ { bool m_bSecondTry;$ H( w- G9 Q( W, ~# u# }6 ]0 i5 {3 z
bool m_bServiceStartedByEmule;
1 e* |# [( T( T6 t bool m_bDisableWANIPSetup;
% T/ c) R4 o) a% {) Q( n bool m_bDisableWANPPPSetup;
' ^: [7 s; }2 @; D* T# T0 E& q5 `2 L; s* v
3 p* @4 L9 S! E! `' p9 a};+ k9 m5 r' I7 O/ o) k$ v
8 V$ e8 F( L6 E! C% y3 C1 q9 U5 i
7 f, } |9 w; K8 Y- I// DeviceFinder Callback/ W) c# j, j# b6 ?3 k
class CDeviceFinderCallback
* h7 i1 `4 a1 R. r : public IUPnPDeviceFinderCallback
, c$ k3 Z! w3 d! c6 x{
3 l. u! u. y8 _1 Kpublic:# A5 \* [' E( I1 i5 m
CDeviceFinderCallback(CUPnPImplWinServ& instance)& s2 n2 V3 Q8 Y$ n* m, A. Y
: m_instance( instance )
5 H) M& Y# ~% _6 |( w* p { m_lRefCount = 0; }( i: O, o+ Z7 S& }5 s" k
& _' h5 f2 t" ^1 X4 }$ M/ i7 q) T% h+ O6 ~
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
3 F6 @( q( p. X6 R8 [! O9 Q H STDMETHODIMP_(ULONG) AddRef();
& U9 J2 x; x# v' V6 v STDMETHODIMP_(ULONG) Release();5 O+ t0 G+ V0 Y9 f
9 s1 t5 A4 `: _2 y8 B# c! E5 V% q3 y6 g5 C
' E2 K7 W8 e& C3 b// implementation$ u( b. D% x$ l2 X4 r& [4 y, W
private:! k$ k3 B4 w) W
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);& d- N" T1 `# H. U% B: u" o
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
) |4 y7 k% I% C( T HRESULT __stdcall SearchComplete(LONG nFindData);
/ l) ?, N4 C s1 R) q* c( K$ b+ a$ r7 y6 V
/ }6 ~! l, n; B4 `
private:6 t# {& C6 _7 P: _* d
CUPnPImplWinServ& m_instance;& H1 k& s- G; `2 t
LONG m_lRefCount;9 U9 u0 o+ B2 h( T7 @! V1 G
};1 F: p% t! c+ ^# Z( C
! {0 t0 a+ V9 L3 f
- I+ h; W0 j& f# I3 I7 x! V P b
// Service Callback
, N* u0 i9 Y6 ^- o/ y' H2 fclass CServiceCallback
! Z. G- ?: O5 K, F4 j: c$ T : public IUPnPServiceCallback0 U! G) P' Z" _0 p: S9 z
{3 N. G; H) E% p) l
public:( r9 {$ q& W' r& M5 l% j
CServiceCallback(CUPnPImplWinServ& instance)
) A0 I& o! ^# o9 A/ P : m_instance( instance )
8 I# y5 b4 N2 D* a { m_lRefCount = 0; }
1 e/ U2 z1 h. O& C# ~! M, B
3 n! y( @3 z* M5 q STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);% `6 a5 h2 {: U( `$ [. J9 p
STDMETHODIMP_(ULONG) AddRef();
# p$ K, Y. z/ s+ n8 o. e STDMETHODIMP_(ULONG) Release();
& R& z: K8 X$ h4 a% \+ M) s8 G- i+ Z S4 ]
8 Y" n- i U) G6 D. @7 ^$ f// implementation: e$ B$ K( I6 ]# C' P) w
private:; _4 |. L8 h9 b) o) K* Y7 B
HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
6 @, ]+ P% l7 M& U& r7 L HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);" q: C) f2 P; N* F, o$ ~2 R5 K
" ]0 @4 B9 b9 A% _* u# O$ C0 D$ `
private:5 {+ m8 b1 L S; L1 C) q
CUPnPImplWinServ& m_instance;4 s, p& ?& M' v. J5 u- E- e
LONG m_lRefCount;
+ Q4 C! f$ S0 ^5 H" t0 S* P5 j, N};
% S, P, [$ c( B# d1 Y
E8 c* K ^: B/ n! ^8 e
( ~3 W: J. h/ f. h8 V/////////////////////////////////////////////////
, K, @5 \ Y6 m6 h
4 N9 R' P* Z! a1 T+ n: R" Z) Q" U2 f7 ^
8 k) |9 c8 K7 c2 s- L5 P/ @* J使用时只需要使用抽象类的接口。8 @7 X i8 U% m+ d% u
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.$ ^5 \+ A" f* e; k5 G
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
( G$ A+ I6 n! p# p( R( S3 MCUPnPImpl::StopAsyncFind停止设备查找.
0 d( d' Q* X9 f0 k- zCUPnPImpl::DeletePorts删除端口映射. |
|