|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,( n4 j" w& U* y
$ d% \: x* Q" c1 O% V2 Z
1 y: W4 C# A- t2 l- O0 a9 A/////////////////////////////////////////// [* ~7 p Y3 f4 t. J! r; K9 r! |2 M) m
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
9 }" U. v8 I' F' [) `3 j# y( C* V! M# e6 m0 X! X8 C7 j+ \* i
. n3 t2 i2 \: X
#pragma once8 d4 X2 Y7 b: i* n6 b
#include <exception>" p2 n2 Y% q2 q B- @) U+ l
# M; C- h2 Z' |% W7 C' G6 C$ P% f6 I2 q6 i* [/ p4 W/ S. [
enum TRISTATE{
* n5 ~0 P# P7 G9 f% m9 J TRIS_FALSE," a- ~( L( ]: Y+ b% w/ }+ T r2 g
TRIS_UNKNOWN,
# Z/ k: M2 L5 }& k$ K/ t TRIS_TRUE
4 z8 b% p- D6 N6 T1 N};& R* X& Q+ r" r3 @; K4 A
+ J9 U; R( u4 Z1 g5 l) d5 r- V
/ i& v" H/ ~( \" [; kenum UPNP_IMPLEMENTATION{2 |8 b& i0 ]% \7 W7 O
UPNP_IMPL_WINDOWSERVICE = 0,
, s: F0 t: q. u! z/ v3 o UPNP_IMPL_MINIUPNPLIB,
) ^. H9 j7 A( z& U( y UPNP_IMPL_NONE /*last*/
6 E9 L- O; ^- _/ o. j" @7 O) }! f; z: [};* N1 o+ Z) W/ i2 M8 |
- D; L2 Z+ s& T+ g8 p5 t. P
3 B- y9 O0 P) d( {6 S0 v
* G. c$ f) W9 l& f! F; {
; a' H- u5 I% j6 P8 R9 H( H
class CUPnPImpl
2 z9 v' Z' _7 T$ s0 ]& n{3 Z: U3 i. d1 K5 [2 {0 C: f3 \
public:
3 A' m/ _9 i: C CUPnPImpl();5 S! j' U# r' p: M: g1 R5 o; S4 [
virtual ~CUPnPImpl();
; b7 h4 D! L) K; | struct UPnPError : std::exception {};7 n: X, ^( t$ m' V. T) }
enum {
+ B$ i" q9 q6 u1 B2 O, T- F, j UPNP_OK,
0 u7 p2 N: p1 l' F+ }( Y UPNP_FAILED,
1 j/ z( J+ |8 G8 c! F1 P0 g# N' D0 | UPNP_TIMEOUT( r" @1 L; M S c8 @) _4 a0 \( A- v
};7 n' s7 e. Q) w# k
# M* J# C) c$ L5 Y
2 o% ^. M- t# m+ w/ \6 T) ?& q virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;5 X3 f# M% G9 T0 R2 _. l* v+ F
virtual bool CheckAndRefresh() = 0;0 M+ p' a Q! z! D( D8 @6 m: ~
virtual void StopAsyncFind() = 0;
; I7 j/ R$ P; X7 M" f virtual void DeletePorts() = 0;) s( o" g- u" R/ P( A1 ^
virtual bool IsReady() = 0;2 Y) N# K8 G6 ]/ |. `/ H7 b
virtual int GetImplementationID() = 0;
9 [' w, @1 }! c8 A
8 Z+ N& U M m( p: b# B- ^ void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping) X0 N! E+ k1 x o
( a9 P8 x0 I& v+ E8 A
' p& x: h& M$ V5 I V void SetMessageOnResult(HWND hWindow, UINT nMessageID);
9 S* S" U( r+ y7 N7 |& V2 C8 W( P TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
$ _) X8 _+ w* |. Q; C uint16 GetUsedTCPPort() { return m_nTCPPort; }0 |# C- c& c! G7 r. P- x- V( Z
uint16 GetUsedUDPPort() { return m_nUDPPort; }
, B1 K: H5 ~" Y7 q% `% W$ g9 d$ O" |" D
3 ~$ Q2 t4 l* a. S
// Implementation
, r" v3 J- u8 P ?$ m' Lprotected:
0 v4 w- n. {3 B7 g$ |4 } volatile TRISTATE m_bUPnPPortsForwarded;' o6 z+ C, X! D: k* X: L$ Q5 }# k
void SendResultMessage();
; V, n/ {9 _. h( ^* [+ h uint16 m_nUDPPort;# ], r; j4 Y' {) {; V8 ]5 @
uint16 m_nTCPPort;9 e: V/ T( \0 B
uint16 m_nTCPWebPort;
0 l0 j" c7 P+ a+ l n$ t. p bool m_bCheckAndRefresh;
" U. Y: l4 B6 l4 V
$ _, L8 h2 s% L) a
" e6 O5 O+ Q* @8 I+ E: f* Aprivate:$ S: @8 Y- o, w9 V2 V" v
HWND m_hResultMessageWindow;+ c3 h0 |7 g" Q/ b7 ^5 n) c! o
UINT m_nResultMessageID;+ Q: f" q. U9 {
9 c# `2 d2 w4 T( [( J7 {5 g! c
( Q3 g0 g' k6 ^9 D' W4 _% A
};) ~4 A* ?& q f
( J6 Y0 o1 R# @/ J" Q V6 V
) _$ j$ u+ l+ C- |/ D+ s. B
// Dummy Implementation to be used when no other implementation is available8 ]2 M8 V3 ~4 Q$ s. F0 u- W
class CUPnPImplNone: public CUPnPImpl% _: u5 U. e# I' u
{
& N0 p# @8 }% F6 A9 b- Ipublic:( Q8 D4 o: M6 Q b; _" u
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
/ y( M' C* f M6 H) D) B) g virtual bool CheckAndRefresh() { return false; }* r) @8 O0 j1 N' g, R3 H! {
virtual void StopAsyncFind() { }: ^/ f6 k q1 P2 T) m! K B8 }" J
virtual void DeletePorts() { }
9 A. e D7 W) r7 w: K6 k- P virtual bool IsReady() { return false; }0 B* I& E, z7 a0 u, j2 s* G8 F
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }$ e& g; b; F$ o
};
/ B" t7 ?8 _& j9 }6 T$ ?2 z+ x6 i& S( Z x3 {
G3 R* r7 W, t' T5 Q9 v
/////////////////////////////////////! d( {7 x' ^* _0 G( C- i
//下面是使用windows操作系统自带的UPNP功能的子类
, N& B( {; f" q' M) }2 W6 {8 b! C: g% S
?3 S( [+ K; x9 b# G#pragma once
7 [# {# n- p" F5 q7 }4 G. F! M#pragma warning( disable: 4355 )/ x) J f$ i4 t0 S1 Z, e: Z7 k
# }2 ^1 M9 y* ~) }; V' [1 i2 S8 z: w: s1 U, p
#include "UPnPImpl.h"
L3 G1 T4 x6 ]$ a#include <upnp.h>, U* o6 ^8 W p' [& x7 E
#include <iphlpapi.h>: o5 ?# C7 Y5 O. m! K1 o
#include <comdef.h>
7 T$ D& O& p" K" b. x#include <winsvc.h>
/ y' W. ?0 T! b2 [
" x2 D4 H8 O' B2 z) V; e* H
. |. t5 x, V6 \0 s#include <vector>6 _8 y5 V. J: r: p: s. U0 {! b
#include <exception>* s( F3 ~% z, }2 d
#include <functional>" k) }" F' e7 H* x n) b
$ V! ~9 u F' m" e
7 l; w* B; q1 U& L+ j# L: l) e3 Q7 v; j8 x5 ]
8 U+ N9 ]8 N& ~8 R. g! ^3 `0 J: ~typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;* Z7 M; v0 z: n
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;: u5 u1 f5 ^, k# |0 d
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
/ u% O% m: s' |5 C8 Ktypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;) ^. B+ d. K8 [# A% S2 C6 c
typedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;$ u: e( W# u* R$ ^3 P
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;
* o$ o l1 p' S& n; e% X& Qtypedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;
* [: B: w' O$ S5 A1 Q8 s7 d, p+ x; u+ y
$ l& e5 `. p) y4 W$ G M% Z6 e" Z9 Etypedef DWORD (WINAPI* TGetBestInterface) (
B( b& F0 I: Z$ L- D( y7 I IPAddr dwDestAddr,
. {4 k# M% L, ]( x! F4 a PDWORD pdwBestIfIndex
: j1 \7 i }, \( B);
- @7 r1 H @) x+ G1 b! v6 G
! t6 J/ y6 o5 h5 c( E
5 H3 _5 c6 _6 @+ o9 Gtypedef DWORD (WINAPI* TGetIpAddrTable) (
& G6 M8 R7 L) ^+ Z- T6 q PMIB_IPADDRTABLE pIpAddrTable,, c( f( U, x- I- ~$ C4 M7 A
PULONG pdwSize,
" y) R2 O2 J9 P7 A BOOL bOrder
1 q y# D. B8 Q0 ?4 b0 L2 l);
* C; Y: z. s7 n( V5 ~* a+ O- ^
( m& B0 [$ h/ B/ w% g: n
/ p. D) H- G Atypedef DWORD (WINAPI* TGetIfEntry) (, Q( Q! S3 x0 t8 s/ C E1 G, M
PMIB_IFROW pIfRow4 `" `8 n& h) @& H4 \% F M4 H
);
3 q/ f/ Y& e8 d' ~* e; ]
; n+ `5 s, }- u1 m" q
2 l* w" {$ a& p: l B: c' zCString translateUPnPResult(HRESULT hr);* d& ~" c. ~* k( q
HRESULT UPnPMessage(HRESULT hr);
- {+ q! l. F. R. n1 S4 A' x/ g9 v5 F+ Q( h8 X
^! e- `9 B8 v; [
class CUPnPImplWinServ: public CUPnPImpl* Q# S+ M: N/ T9 L) Y
{
8 W% f4 B% Y# v, a: C friend class CDeviceFinderCallback;& i# |) K0 F# [2 X: Q8 ~' {) E7 b
friend class CServiceCallback;3 g \' x$ d3 d
// Construction+ F+ R! b/ v& ~5 Q) F# T
public:
" h( e3 P4 p2 R n1 u5 M6 r. ~4 f% { virtual ~CUPnPImplWinServ();
1 S- q9 w* S4 d CUPnPImplWinServ();8 F( G E4 }- o2 i3 e
# j. u& p# H/ d. x/ c s! l8 M9 n! A% _, p4 M, B
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
8 F: D% I/ b% Y$ B+ J virtual void StopAsyncFind();, K$ G' O* k8 J
virtual void DeletePorts();
& R6 ^" _( q2 T) n$ { virtual bool IsReady();9 { r/ |" U, P, T
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }: {) R$ c, ]- D6 I3 z
0 M4 K( I3 `' j& y8 G$ A
8 x9 }+ t* w0 B) {( {( b // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)
% F1 z Z2 X, u3 C) {6 T // the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
. ~, Y1 G4 H Y8 ^8 f virtual bool CheckAndRefresh() { return false; };
3 A8 U" E$ ~$ I4 L5 t+ d) @' z1 e' c
5 y! a' Z" D- o; I+ aprotected:# t% `8 }6 e( q" }# {
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
, n1 k& T+ }( q) Z8 E) E& b& r+ X4 P( d1 _ void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0); ~9 d0 n0 m6 O: E* m* c
void RemoveDevice(CComBSTR bsUDN);5 y* Z; n, B. T5 N' Y7 _5 ^
bool OnSearchComplete();+ f6 ?7 E: D9 k2 \& {
void Init();
8 P7 @3 f8 i* X) L3 Y- H$ j" l8 e4 h, \: k4 m& Y
8 R& u* W7 j f* L inline bool IsAsyncFindRunning()
3 p% G- i$ r. W/ [% z$ {& i {
: ]) i! Y8 {' d" u6 Y% H$ U if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
$ A% A% A3 v7 i5 {* g {6 f3 R8 N5 [7 P9 Q* j
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );+ \, ~0 U: W' X% h; T% P. C
m_bAsyncFindRunning = false;, j, h' z5 j8 d) i8 j, Q) S& K
}
9 C& _1 F1 P8 Z1 k3 D! `6 j MSG msg;6 d2 j7 ~# P) R& v4 C3 y
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) A8 R2 J6 M8 n" u6 }, I
{
- B6 Q0 M9 L$ i5 C, P2 o TranslateMessage( &msg );- C0 X- H7 g: S0 R* t' V1 M
DispatchMessage( &msg );0 ^0 W7 @( U* s" s
}
7 w+ ]- U0 e4 n" J return m_bAsyncFindRunning;: {6 e2 F/ u% |+ _: s- ?* w
}4 A, `4 \, I9 k8 K6 Y; x0 S: s
6 _, ^# |6 O" S
/ t1 B! s( H; i1 O" K, u4 U; h TRISTATE m_bUPnPDeviceConnected;
3 C6 Q; U4 y) ?, P, I
, f" N4 V5 u3 G$ v$ b8 I( r" q% N4 ?, s+ p6 s
// Implementation0 @! N1 V; j2 Y: M
// API functions
: k+ j4 r) s* h6 d) O( {! z SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);- Y0 b$ V% G* p! I- r
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
+ ~1 R0 Z& a5 J% k# z( r BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
5 j/ |+ _" Z+ a$ Z BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);& y0 ]' u: K, O2 B$ h$ K0 T/ B
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);* `! c/ d6 h( u) S* j2 o* F
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);7 C; K/ }% ~3 m) {+ ]% R
2 Y( P+ S1 h q5 L
+ @( x* c! ~2 f4 @ TGetBestInterface m_pfGetBestInterface;
# ]4 A w% h: W' _& X3 B TGetIpAddrTable m_pfGetIpAddrTable;8 u2 k1 s8 S5 h! v: M/ e5 x( u
TGetIfEntry m_pfGetIfEntry;
1 M. C5 {( K& n4 @5 ]+ R+ b% Q( q2 S* D+ u
$ ]- O9 g: [; J$ E5 G: y static FinderPointer CreateFinderInstance();) O2 o5 r2 E" r, m z& y) F
struct FindDevice : std::unary_function< DevicePointer, bool >
! Z3 R8 ~, K8 q2 T* `0 d {
3 a" j, e& Z, ` FindDevice(const CComBSTR& udn) : m_udn( udn ) {}& _3 | q" t; L. \( n& [
result_type operator()(argument_type device) const
5 ?0 T/ h1 H' m* y* h( f {& T9 l! l$ `" l# L2 Q& B1 `5 \ }
CComBSTR deviceName;0 w F8 e9 c% {$ G3 ^
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
6 t8 S) f. F; S! ^0 ?2 u+ }# e: E4 ` S2 p1 ^ w- U
$ ` Y5 D2 k1 Q% w o9 P if ( FAILED( hr ) )
& i0 R6 r B5 z2 f3 f return UPnPMessage( hr ), false;
/ V, A. |4 {+ _( \, v' M: ^3 {, @# ?
& ]& ]: f* }( P7 w0 i
return wcscmp( deviceName.m_str, m_udn ) == 0;
7 e3 `4 E9 R" q7 {: Z3 k }
6 v5 \0 I! V K4 T7 v CComBSTR m_udn;) K" S" F, _2 x n& [2 I
};
' e8 h9 b0 B; z; J0 o, t 2 t6 U0 F) e* f! f& L
void ProcessAsyncFind(CComBSTR bsSearchType);
! k7 a* q: J) N1 l" D2 V6 @+ j HRESULT GetDeviceServices(DevicePointer pDevice);9 l1 K. o$ }* a7 f/ D
void StartPortMapping();0 i. Q: @! n% j! ^
HRESULT MapPort(const ServicePointer& service);
0 \( r& R; A# r3 J5 ^- c6 W$ ~) A% S void DeleteExistingPortMappings(ServicePointer pService);
& ~ [. |$ k$ }8 k, _+ Q$ ^$ P6 E& l void CreatePortMappings(ServicePointer pService);
8 z& M0 n. P8 q HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
" w& N9 q) D. Y0 p HRESULT InvokeAction(ServicePointer pService, CComBSTR action,
9 y0 u% Y1 k D- x; d1 m4 Y LPCTSTR pszInArgString, CString& strResult);
0 f/ t3 H2 V7 f9 C) @ void StopUPnPService();
/ y! v9 m7 q, K* }) K& E& R& ^3 w" j9 D& N( q
! `4 z3 d4 O, u3 d' J: s
// Utility functions$ M+ a7 o n2 h
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
' K8 t5 J9 p2 x: f/ ~" ~$ J6 y INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
* z7 h2 T2 ]# H: w7 w2 ^! a/ G INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);0 o4 T& m. k0 X0 V, _: B9 P W
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);+ L% _- }6 K% J: t' G
HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);, A2 y# N* f7 p4 P0 ]9 E; j' T
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);
" {; R8 z/ ?4 Z$ e" B. { CString GetLocalRoutableIP(ServicePointer pService); Z; S8 @% X! v: I
. _1 C" H- p4 F0 B) K) c& q8 h
. a+ T$ E( r! y* k( c
// Private members
* E" a3 a- z8 d; Cprivate:
( [$ i& a/ V3 H% t# p: C DWORD m_tLastEvent; // When the last event was received?
/ W2 E: \" F P3 q) N! \5 k# E5 I std::vector< DevicePointer > m_pDevices;
1 r$ \/ i1 V, [- l std::vector< ServicePointer > m_pServices;
# S& Z, {6 X$ I, Z) K5 u FinderPointer m_pDeviceFinder;
" J U4 [, E8 \% W; S" U% ] r% r6 @ DeviceFinderCallback m_pDeviceFinderCallback;
5 s5 S+ |7 `( |" u& n ServiceCallback m_pServiceCallback;0 q" ~2 _, i0 O- A3 C. e+ _
6 J& s) y% o( @
3 U; E& e; t% U4 N- Y3 b LONG m_nAsyncFindHandle;
B9 u+ ^' Z3 D1 f V: H bool m_bCOM;
+ H. p, \ p8 }4 R3 B8 q bool m_bPortIsFree;
, U- h9 f- C0 c CString m_sLocalIP;
5 k. A0 e x5 n0 J8 M, Q0 P CString m_sExternalIP;; s& a2 X% b8 i6 H `2 c3 Q
bool m_bADSL; // Is the device ADSL?8 K. E" ]$ m9 o; M, q; }
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
5 ^4 f) c2 C! I/ Q# I# o0 h' T bool m_bInited;$ U, F* O$ N- J* [ a8 D; d
bool m_bAsyncFindRunning;2 L( P3 h8 L5 e* ~
HMODULE m_hADVAPI32_DLL;, R3 p& e$ Q# o* K, B
HMODULE m_hIPHLPAPI_DLL;
( A) {' w2 a0 _* b1 B' j: ` bool m_bSecondTry;. B7 u2 {! h1 F, R* @/ I; I
bool m_bServiceStartedByEmule;, T A5 i! U9 C _2 b0 B" t3 B
bool m_bDisableWANIPSetup;
& I& E% L: e B% ^# }7 W0 p' v bool m_bDisableWANPPPSetup;
9 _* q c/ D$ i9 J1 a8 n( |3 }2 x$ W1 ^( V3 i' k4 ?
/ S& q9 T8 D5 i' K8 ^
};( i9 f; I2 v; I. y; `
, A/ t0 n) `0 k; ]0 k% S5 r
- Y1 ^6 I7 ^9 l" j// DeviceFinder Callback6 V# N+ A- ]5 L1 Q$ y
class CDeviceFinderCallback
* \1 G$ j2 [% Y+ c : public IUPnPDeviceFinderCallback u$ Y' M4 ^1 \. ]0 ]$ y( i: H6 N, m: t
{: e4 @. j. m, Q0 ?$ z ]0 K- Q& f+ _
public:, x& a9 P+ g/ O# H+ n, i2 O: i
CDeviceFinderCallback(CUPnPImplWinServ& instance)7 f6 [, S5 @; t2 F) _8 M& R+ M! u
: m_instance( instance )4 e# B) d# w5 K
{ m_lRefCount = 0; }" E: f- y; b; Q& Q% ~: k0 f
1 A1 w* d0 X4 P! x1 o E# P
Q; c' |6 a3 |- @ STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
) j5 h, n4 c" U) [5 y/ W$ A9 F STDMETHODIMP_(ULONG) AddRef();7 u1 X. k- C' q$ `
STDMETHODIMP_(ULONG) Release();
5 a" a, E* @; ~+ p: ^8 s* U( ~4 x/ C3 ~ G
* I3 n% G0 R8 i& B$ v
// implementation
1 y8 J& ^( r4 [- t, n! Oprivate:0 {9 K+ D* d1 K0 p/ W
HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);" s0 l7 U. [7 Z# }
HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
* Y, D- a# w: J5 } HRESULT __stdcall SearchComplete(LONG nFindData);3 O$ m. w, c+ G: g7 ?0 P
9 `6 U) F- w k1 _
$ o1 b- L. D3 u* c8 {
private:
& u; R9 ~' Z4 j& b; e CUPnPImplWinServ& m_instance;4 F! A- f) |2 w1 C& L
LONG m_lRefCount;+ U0 T- Y5 p6 {
};/ h! R' \/ N: ?1 e) l
' U; V ~9 a |2 {1 w. `' c( f
+ o' U+ f) p. V7 X; q+ X& l5 l// Service Callback . S! K" F% e; p) a& f
class CServiceCallback6 H$ h) m: z- |. s' K
: public IUPnPServiceCallback7 K( \& x$ P3 m& L8 l9 a
{1 N3 M; L8 h+ T5 f8 q, T
public:3 Z# u+ x7 d9 U3 _- x
CServiceCallback(CUPnPImplWinServ& instance)8 j; R ]4 Z: M/ ^
: m_instance( instance )
+ C F) W) g. Q% d, |! [- ?4 S { m_lRefCount = 0; }
+ R& f4 u& p5 n# ] : O# r1 H* ]( y3 n
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
# V1 Z) R6 j8 l9 j8 x7 s STDMETHODIMP_(ULONG) AddRef();6 I" ]8 p5 J4 y$ u: h8 W4 x
STDMETHODIMP_(ULONG) Release();
2 a& a) M- A8 {$ u/ c z' J7 G4 }. ?/ z" H# X
$ M1 C& l+ L; _! h
// implementation
- n: G7 d5 Q: A! tprivate:
4 j2 y1 L# F f7 b- U$ [ HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
_7 H1 Z6 r B6 i2 V- g HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);9 a* }$ |4 K% b7 ^" y. @
+ u0 L4 ]" _8 ]: r Z
6 y" P! U g6 P* h& W" d4 a: kprivate:. q, \) e0 w& s2 j( M
CUPnPImplWinServ& m_instance;
2 L6 Y7 D4 Z7 y" W LONG m_lRefCount;% D e- u% s) L! L+ l7 d7 R- T
};
! l4 U5 _$ f, ~+ @
8 Z: C# I' R8 X$ n5 t
) }4 {5 d6 h5 M8 F/////////////////////////////////////////////////, c; D2 y& D$ K6 o( L
1 R4 S: ]) h G0 Q' Q
: e5 s9 ?/ r& K4 c' Y使用时只需要使用抽象类的接口。
* {7 R L4 n. Q( h3 W% K5 O- b8 r( ?5 g' YCUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.: C! p6 N" t2 }" Y
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
6 O; @% H2 F x% J rCUPnPImpl::StopAsyncFind停止设备查找.
1 f9 [6 H/ f& }' Z$ U6 E9 E2 LCUPnPImpl::DeletePorts删除端口映射. |
|