|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
6 S- L, ?) Q, L) e. o# m3 O8 c+ ]
: T% i+ g2 j$ R! ^4 n
7 ^" X8 y4 f% C5 y/ F- U//////////////////////////////////////////// _; H5 T5 Y, \3 ?6 K e
//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.9 k7 Y/ `9 } w* h" Y& X6 A
8 h5 n2 v; K- ~/ o
+ A. S6 f) J6 g# _( H( u
#pragma once
' G/ F4 H( f% U. { P#include <exception>
# ^' N7 j& R$ Q4 ~9 I& `! h. L) l% G+ Z% \& s+ G/ q
! @2 z& a; X' `* A6 k enum TRISTATE{
% p' l$ L7 |/ q) x! Z. H F TRIS_FALSE,
- L5 L% {! x2 T% r! u$ S9 { TRIS_UNKNOWN,
4 i/ V! i2 U, f& x8 }8 j$ P TRIS_TRUE+ e6 K, m( b! P; s# A% a/ e
};
$ d' v! K8 m! Z- {- B5 z
1 O$ b4 D$ V% `7 L" Z0 T; Z4 ~, i' e% Z- q, I. c9 [# S
enum UPNP_IMPLEMENTATION{! Q( P1 ^# V9 O, A0 K5 y1 c- }
UPNP_IMPL_WINDOWSERVICE = 0,
, N& ]2 y$ h& ?+ X9 Q UPNP_IMPL_MINIUPNPLIB,% V ~* K O4 ^8 \
UPNP_IMPL_NONE /*last*/2 `; O4 l# i1 G+ z
};; a& n. J8 a' f6 F4 V
c5 V' Z5 y/ Z$ P
- D+ d* p; p: t* b1 O( P0 t, _6 R. S# c* n8 F/ H# k7 J. X, C5 i
7 i* |, A0 z* [ S! ~class CUPnPImpl/ Y/ R* W- A- I0 O2 {& E
{9 _0 x1 ~. \* O3 m% m1 K( ]
public:
( S0 e+ f4 e. m, ]/ m& k CUPnPImpl();9 }/ s/ E5 ]9 T) U$ h* s3 U
virtual ~CUPnPImpl();
2 D3 M5 C8 m$ C* W% V1 T struct UPnPError : std::exception {}; D9 d- [ d& p- ?( o5 A
enum {
$ a+ a9 C0 H3 E- O UPNP_OK,
2 S$ Q9 L' h7 i4 C UPNP_FAILED,$ j- Q. p2 ?( j/ J4 m3 A/ f& W
UPNP_TIMEOUT
' \1 A, ~6 q* _# h2 n };
% ?. b) {4 ?; e( E( W) K
# B+ b0 r6 q1 ^* k7 H0 T2 f+ \, m/ I! p" U6 F+ O
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;
9 D. o5 C* f3 h1 T& }0 w virtual bool CheckAndRefresh() = 0;% F/ j; z2 j l7 y+ A
virtual void StopAsyncFind() = 0;" d7 ^/ ]5 x/ w% X
virtual void DeletePorts() = 0;
* q5 p" v) @- F virtual bool IsReady() = 0;4 E) p+ ?# w. j
virtual int GetImplementationID() = 0;
$ E3 Y3 Q; N' ~6 F5 Z; |6 }$ ] & q2 a0 L$ {! x7 ~
void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping; z3 J8 [5 X4 j$ x( X' h
4 G+ j$ x8 A& E4 B# ^3 c, D
) a: g' M! `* A9 t5 B! D
void SetMessageOnResult(HWND hWindow, UINT nMessageID);
% A, M# E# R3 h( O( o TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }0 G$ _( H; h5 N/ `9 ~
uint16 GetUsedTCPPort() { return m_nTCPPort; }
. O! p4 p' k5 f uint16 GetUsedUDPPort() { return m_nUDPPort; }
) Z: w( T# Q8 B s% @0 A% o
' m' `. \ @' F, G8 w7 K- {1 Y0 I' V; m
// Implementation
& v/ d1 N9 R$ W% f$ \/ j% s+ Oprotected:+ [$ S0 f6 W4 f& R6 q
volatile TRISTATE m_bUPnPPortsForwarded;
& I" v8 N6 Q$ x$ Q' R void SendResultMessage();" G, R: l5 J/ w/ b a
uint16 m_nUDPPort;+ B( U; U& w- l' L& Z- W! u
uint16 m_nTCPPort;3 p8 H$ V. e4 O9 S' s$ l8 `
uint16 m_nTCPWebPort;
# N, U- ^- {$ R; ~ bool m_bCheckAndRefresh;
/ ~& m! Q9 L: t- E0 p9 P$ t+ g; x* y( f9 i( s8 J
. L: ^: M7 R' l1 tprivate:
! d) I/ \4 q& P" [( a1 \ HWND m_hResultMessageWindow;/ Z3 }: X/ ^; j" {
UINT m_nResultMessageID;( E# d0 O; M1 L& v9 W1 H) ]
. @1 Z- {7 E \& @6 @+ `0 q0 N1 y/ w# \1 I, {
};
$ a- w8 U+ C+ T+ z& X1 O: S6 E) P. Y8 T" k. Z& ^
. _/ P* @7 x' x# \- B4 W* S// Dummy Implementation to be used when no other implementation is available: j1 X$ C4 o, ?( u2 q9 J
class CUPnPImplNone: public CUPnPImpl4 p2 \ T, D( L$ @6 Z
{% u& X- Q6 J- R5 o3 A Z
public:
3 y O) x2 ]3 ~0 i- c' D/ i virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
7 ^. n8 \8 _8 L) Z- H virtual bool CheckAndRefresh() { return false; }' L; h$ I3 l& K
virtual void StopAsyncFind() { }
, p6 w8 ^& F1 t virtual void DeletePorts() { }
$ U0 v; p& Y7 P1 Z9 D# x) u0 t! } virtual bool IsReady() { return false; }
; y0 S( p- p% r9 Q. z* y8 K! v3 R virtual int GetImplementationID() { return UPNP_IMPL_NONE; }
# m# A6 Z/ @ j# m, \& _};" w- m( @ h: E: G0 h
/ S! ^# O4 B1 ?" O
/ G+ o; y U$ ~- m$ k3 k8 O7 E6 N/////////////////////////////////////
4 b4 _$ ~. _* S& c//下面是使用windows操作系统自带的UPNP功能的子类( o5 b3 c8 i: s& D; B+ S
$ \9 y& i# u* I3 r* A$ L
3 [ G! a j; m% o4 l#pragma once( n1 }3 S+ L0 o' t
#pragma warning( disable: 4355 )& ^! @2 k# n; @" ~3 @
/ G( c, k& |9 X. L% v
7 A5 l6 \0 L: k3 d#include "UPnPImpl.h"
1 t, E( w$ i9 V) B8 O#include <upnp.h>$ ?" W# Q- [% n0 `( j& m/ @* Q7 T( S) m
#include <iphlpapi.h>
+ F' H$ U4 I) g- n#include <comdef.h>3 ?) A7 W) H. O$ ]! y1 J
#include <winsvc.h>
8 |, Y* ?+ w8 ?2 m' b
2 Q. C. O0 }: V& C- e' t: q, L1 ?4 s: V5 | G3 i) y
#include <vector>
* R' K) _) I( o/ R3 @5 Y#include <exception>4 n+ k |8 K" c/ ]( d1 `0 [
#include <functional>) S1 s9 k, H# K
2 c4 ^6 h5 \, E0 \' Q$ x5 o
- K+ r: I0 T) V) w3 w
; ]* F: M; X; |" J5 m
6 r5 l! x+ l9 i8 L. `typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;+ ~$ |) {% \2 @/ q
typedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;
( O, N$ j4 P# Q- Vtypedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;, B6 o+ O& l C0 m
typedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
; {/ q/ d- K' f/ ?. A* Dtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;$ m4 g$ {. k1 V' b; ]- P+ F$ l4 t) o
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;6 F, o6 G# G4 I4 A, l. S: I& c V! m
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;0 U' H3 G5 [- ^5 p' R
! o( D! C8 |/ \+ F' R* X! _- {9 r
! v/ |& O" g, stypedef DWORD (WINAPI* TGetBestInterface) (( J4 z4 s5 v7 I. l6 ?0 ]: A8 @
IPAddr dwDestAddr,
$ w7 ~, {% H% Y+ ~! I PDWORD pdwBestIfIndex
h3 }- `7 R& e$ P' K# t) x8 q);
$ v# f( ^8 Q& c; o
$ I) c% ^6 R* w1 {- R; k' Q) T( g% b5 |' c5 l1 U! C9 L
typedef DWORD (WINAPI* TGetIpAddrTable) (
$ Z W ~) s; e! h, i PMIB_IPADDRTABLE pIpAddrTable,
4 I- q F# A- N! B e6 u W PULONG pdwSize,: ]4 a6 O# c6 T7 P! q) o h+ I
BOOL bOrder
" m0 `0 ]+ V2 w% k3 Y);
" R6 ?' N* Z" J4 y2 m* q* n
' h0 t2 D- e1 y$ }+ t! D. |" |" l [" U- o& U3 r. Z3 z7 F8 b& c
typedef DWORD (WINAPI* TGetIfEntry) (
2 j# }; K2 n$ O, C- R: { PMIB_IFROW pIfRow! h9 L: m8 J' _4 L) C9 m
);2 A: P3 L3 S& a; q
4 `( o2 X! h% r7 F7 G2 C5 A/ w0 Q/ |! g4 q, |; }: Y: u( T
CString translateUPnPResult(HRESULT hr);+ S0 C: z$ g# r6 k n
HRESULT UPnPMessage(HRESULT hr);
/ R0 c; q1 B0 D% R- \; B/ Q
" G4 N. Z9 O6 C8 Q# d( M
! P7 |9 k3 |; }" m7 i. C1 gclass CUPnPImplWinServ: public CUPnPImpl
4 q& N% J& Y5 L5 }# F$ e{) f8 o- a4 G5 H. _) \
friend class CDeviceFinderCallback;3 {- F4 g# { n2 B
friend class CServiceCallback;
) t; R' @0 P1 f4 ^// Construction
6 P" ?5 m$ J% y8 B1 @; ~+ Ypublic:3 H4 M" K c7 \. P2 C- ^% F+ M
virtual ~CUPnPImplWinServ();
- m/ t# y0 s( ]* W# q( J2 [ CUPnPImplWinServ();
) o' B; k# P( N8 {0 p
9 c& h: n: Q( D7 h: W- l$ I: b: j7 S3 R! G& Y* w1 H" {- @' l' f" h
virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }
$ w1 L/ _# L. }) S1 B5 k virtual void StopAsyncFind();. ^0 U9 S4 A5 f9 y* [9 r5 W
virtual void DeletePorts();- J1 E# }& T+ C$ ?2 `& r4 P, P+ u
virtual bool IsReady();
1 y5 k2 c9 E7 }6 ^1 B) H) {' X: w virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
4 ^/ a# [/ P9 p
. ~$ b8 {8 _8 t2 ^0 [, u. z9 M
# H6 [8 x+ s# Z! Y* m/ N0 I // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)1 I [8 ~0 ^ D% o4 z$ @
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later
6 h9 Z" q7 z7 P/ x/ ]8 \ virtual bool CheckAndRefresh() { return false; };* O( `. u' g7 ^3 @0 c
; @) u$ m2 h6 g. D; W
$ c: ~& y1 ^6 I0 |; H) i4 o( U: Oprotected:% H7 R' G x6 H$ l! {0 w
void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);
p( s+ d9 q( `6 Y k void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);
5 d) D. V' g0 v9 I9 ?8 ? void RemoveDevice(CComBSTR bsUDN);( t$ n1 n6 _- a
bool OnSearchComplete();, K7 G; Y B6 w9 G @4 t
void Init();/ @% R& b8 d- r% Y/ B
, O# S# O0 E! X: ^
& w8 i8 w" s' e' l& s; j; h. y inline bool IsAsyncFindRunning() ; u3 @) I! D% i k; a8 Q- u# Z: \
{- `: C+ I5 d7 F0 }* t( L
if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )
. N1 Q9 l) H0 S3 y- Y# D& O {
2 P" |2 u% x( B/ i/ J% W1 J) U m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );/ u# T! Q: p! J- t# A5 K* _8 Y
m_bAsyncFindRunning = false;
1 }! I9 O. K9 s }- Q; \3 I. e4 o1 s0 b/ Y2 ]
MSG msg;* f' c3 R" {: Z V
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )3 o9 N9 O" }' Q$ O9 [
{4 @5 Z/ }/ K- c+ P; S! x5 H9 }" C; I
TranslateMessage( &msg );
. H/ G( N8 k' ?$ s* Y$ p DispatchMessage( &msg );$ p& Y* G J$ Y' ~8 D/ F( Q+ W" n! p
}
3 p0 J) C* x" t8 w1 ]0 {- [6 A return m_bAsyncFindRunning;
. t9 j; J! k# x$ \ t$ g5 U$ e }
3 U% E9 E `- y) F2 s z$ N' @$ V7 b7 e# E2 K
) Q9 e* m- k& b! v, r( } y
TRISTATE m_bUPnPDeviceConnected;
- M4 \6 F' K! d9 L! ?3 [( |9 D* Z# z: L! L
& c) y) R2 ~5 P$ v! b// Implementation% D. d9 T2 C/ I7 P6 q/ X# h
// API functions" F) |- o% {! h- I, I* y2 I; w
SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);8 F' [0 u$ U3 E! ^* j
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);
2 O% l2 `( k- P& Q" R" ]* N BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
( F. g8 R, p3 N* M1 |+ ~* p' W BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);
# f) l8 j; |5 S9 o8 @3 p0 D0 F BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);# F. X* U% _/ ]2 d8 Z! ^
BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
( D- x- c3 z! b* r- W
# @) c( e' d4 z4 _4 Q6 U' E+ H! o6 {
TGetBestInterface m_pfGetBestInterface;
; F5 E& q% l9 u p. y' a+ O TGetIpAddrTable m_pfGetIpAddrTable;& P: l+ P% g* V+ O: L
TGetIfEntry m_pfGetIfEntry;
2 h7 E9 X$ L0 `) m$ a
9 J/ R& b8 C7 Y+ j T- d" M, K
( V4 X, {9 E& i* o [5 ] static FinderPointer CreateFinderInstance();) i4 h9 e5 @9 Z7 n
struct FindDevice : std::unary_function< DevicePointer, bool >; t! C9 s# u+ X1 |2 C. L8 M% C
{9 D$ y# M+ G9 \7 k q
FindDevice(const CComBSTR& udn) : m_udn( udn ) {}2 h8 l. ~# b5 o; C' m
result_type operator()(argument_type device) const5 k7 k3 ^8 K! y& ~
{
7 d; M" F( O8 n1 d+ { CComBSTR deviceName;2 w& A! X* `2 m; ~, z
HRESULT hr = device->get_UniqueDeviceName( &deviceName ); Z, `' O2 F, o7 A9 r
2 S: K8 L O! W) s
9 u" s- {! t$ ~4 x0 F if ( FAILED( hr ) )" S/ r" J8 j- u( x
return UPnPMessage( hr ), false;/ W- r9 M; Y! b) ^ p# ?! i
8 y* D7 j& q4 C" t+ R" t! h5 n6 O+ K* b, V
return wcscmp( deviceName.m_str, m_udn ) == 0;
' X( l, t8 l* L5 U9 ]4 @ }
0 j# Y' H, G# C C+ k9 Z/ K CComBSTR m_udn;3 m7 o, @: a y5 I5 t* v1 t# v
};
7 X" B& P2 Z+ v, f, E, j& i ( `+ I7 Z: K$ C3 S' ^
void ProcessAsyncFind(CComBSTR bsSearchType);
7 B- i- Z) A* ~- m% m HRESULT GetDeviceServices(DevicePointer pDevice);5 s' C3 Z7 N8 f& d2 b
void StartPortMapping();; f" n; c: z8 e, p
HRESULT MapPort(const ServicePointer& service);0 v2 E: _8 d* x( u2 c
void DeleteExistingPortMappings(ServicePointer pService);
. K n' w4 e3 h. L/ a- { void CreatePortMappings(ServicePointer pService);# I" m# ?* c3 F
HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);
3 u* {) G) \' ~5 Q( u' m HRESULT InvokeAction(ServicePointer pService, CComBSTR action, 5 H* H% b6 q; d) L3 [) I' e
LPCTSTR pszInArgString, CString& strResult);9 L- M# z+ H8 q- v
void StopUPnPService();
' O( X3 D/ R) G1 F5 P+ ]; i( M" b# }! r2 t
: s1 C3 G( }$ g2 c4 \- V
// Utility functions9 N. L+ @" S) E+ @' r6 H! F
HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);5 v3 m) I( e8 t$ @- M9 K
INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
! g! l, _- Y) ^ INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);
+ C+ S0 M! S. O" C( f$ k$ \' f void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
6 s8 M9 j: E" D8 h HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);+ Q$ j* j3 B: a0 @
HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);' R4 j8 X; H6 f3 L1 i- c- z4 e
CString GetLocalRoutableIP(ServicePointer pService);
; |( k4 |' q/ [1 ?) `* y
7 x' s( c0 e. s! `% l. A8 V5 c6 a1 ?# z- r
// Private members: ]1 u& K1 H7 v+ K; c5 N8 C6 ?# Y
private:& [; h! x G3 A8 F. N
DWORD m_tLastEvent; // When the last event was received?
% m8 A. d8 C, t' a, }% N; j3 z! x. x std::vector< DevicePointer > m_pDevices;
* H3 I% N0 N1 Z8 J+ ^+ u std::vector< ServicePointer > m_pServices;6 m5 u- |1 S% M' { }! `
FinderPointer m_pDeviceFinder;; n; I) G$ `! j) Q5 u# J; l
DeviceFinderCallback m_pDeviceFinderCallback;- j- K/ F5 S" b' V" B" `8 p3 {, \
ServiceCallback m_pServiceCallback;
7 |2 ?6 s5 M# @% z! H! {# K" Y' p; D$ q
/ n$ i6 {9 y9 @% q0 p5 {3 o! @ LONG m_nAsyncFindHandle;: g/ Y+ R1 |8 Z2 G7 o8 `2 A
bool m_bCOM;
# j4 R0 c' Y5 H7 w4 ^8 I3 X* l bool m_bPortIsFree;
, J3 T. Y* V# ~+ q! t CString m_sLocalIP;
$ e) [5 L9 Q" V CString m_sExternalIP;: a9 q6 d; ^, Y# {1 Z4 }# M' A. U
bool m_bADSL; // Is the device ADSL?
) K9 V. n3 ]+ ]( s+ Y$ r bool m_ADSLFailed; // Did port mapping failed for the ADSL device?
. t; ^3 v2 Y8 ~ f bool m_bInited;
* E0 z+ U3 Y0 N# B' R bool m_bAsyncFindRunning;3 _. ]- V0 }/ C
HMODULE m_hADVAPI32_DLL;
9 i/ }8 l B& F7 t8 d HMODULE m_hIPHLPAPI_DLL;
9 V% J9 n0 u- P! v1 B( u bool m_bSecondTry;- T5 V3 x. I: }
bool m_bServiceStartedByEmule;
3 r. B/ Z: M1 e X0 h bool m_bDisableWANIPSetup;
- O: X2 ?! s& | bool m_bDisableWANPPPSetup;
( r0 V% a ?1 h) y
4 {# n: ~. d1 m, Z* E# w! n, D) v7 ]* N. x9 y6 ]9 O# U" k
};5 p+ f% L0 @; t4 H( q1 X
2 v( @ a! S& a+ E6 M6 ~# t ^
( k4 g' N: ~6 w% F// DeviceFinder Callback
Y$ H+ q0 I9 e/ `% hclass CDeviceFinderCallback
S+ u+ N; M& E( S; a" ~3 n7 ` : public IUPnPDeviceFinderCallback0 m" v& h4 |# M3 k1 F, {, H0 t) L
{3 ]" L7 n* ^% H1 i' H+ E+ i
public:
) \1 m7 R8 |4 Q/ a4 t CDeviceFinderCallback(CUPnPImplWinServ& instance)
& O. Q, ~1 K+ A5 d( Y. F D! H : m_instance( instance )
J! u. e$ j& t2 g$ s' m { m_lRefCount = 0; }7 ]# \- Q" c* r0 f+ @8 e
# @4 R* B) @) C2 k( [3 T* g
# o O" a, }8 I* Q5 x STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
/ j" Y0 l2 h, o STDMETHODIMP_(ULONG) AddRef();
+ x; R3 ^& z9 D3 h4 s; i STDMETHODIMP_(ULONG) Release();) _( \7 d; q0 F+ B4 ~# U" S6 j: ]# t
6 ]; s3 H( T5 U- t; h0 [1 b
( w* V% X3 |4 B- b1 W1 A! x, t// implementation/ M' ]( v8 H- o1 Q, N' |
private:
. p: \; O# q& ^) [' L4 ^ HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
3 O( {9 M( ]0 T* \0 v6 O HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);3 p1 P! D' N! T
HRESULT __stdcall SearchComplete(LONG nFindData);: F4 J0 i5 L# M7 J" q" _
# i* ~% f% ?- P" g% R( w/ u1 y8 N
2 L; n) _; t, p; u# I4 u/ @8 V. jprivate:) B; l/ X( B( y/ R* R: Z, R" f
CUPnPImplWinServ& m_instance;
" g1 ]; p, d4 a LONG m_lRefCount;* y0 U4 C: ^. H) J+ H8 k
};# Z. s5 J) b+ o3 s
7 O2 B9 Z6 e" U: \% P
. ]2 F t: ]1 j8 M6 Z2 U! D( n
// Service Callback
" G2 q( p1 o- Y) B# w. m0 J, Cclass CServiceCallback0 ?/ v% t% [5 z5 d0 r
: public IUPnPServiceCallback# B! P3 @% P" l
{
( j# Q$ C5 i1 y; H# Vpublic:7 {3 j' x) V( O5 h/ K# P
CServiceCallback(CUPnPImplWinServ& instance)
, U" C. ?. E; k9 v : m_instance( instance )
& e; J& d0 ]! Y0 `* N2 ?1 b { m_lRefCount = 0; }
" U* V3 w- I& L1 Y5 _# L( R1 U 5 u: R# Q$ e- L' |, V# K
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
& L4 x8 ?0 L/ Q0 M STDMETHODIMP_(ULONG) AddRef();* e; m/ s3 q' n6 e$ G2 X
STDMETHODIMP_(ULONG) Release(); w. f' D' U7 H: z. G! Z6 N- L
( C0 x* z- O: o6 l6 |) O$ I1 ?: x( G
. e! d1 K0 G2 N/ |9 v
// implementation
! J( j8 d3 X, Eprivate:
- b. A/ {& ^' l( Y1 d HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);1 k6 S/ b& U5 E) |$ L; N& k
HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);
% {: B _/ l$ x! s
6 n: i; C* W, j4 E- `& n. Q1 `. L6 o( _3 G( U: E. ~
private:! P0 I% R, _+ |5 w
CUPnPImplWinServ& m_instance;# n; t% p ^! H" Q9 O& r$ Q" Q
LONG m_lRefCount;
) L$ W9 x, M) l, i; J/ F};4 l! Y, Z# ]! E6 {) L
4 t0 v' F% }2 ~; C! j. {8 x) P* k
% k7 M9 o; {5 S# x$ F, [, Q) ]
/////////////////////////////////////////////////8 r4 o, }3 i+ J1 y
7 c6 k* @& l6 b, W/ l, d0 U) T
5 j* D9 h; w& `& r" t使用时只需要使用抽象类的接口。( ] a0 k. d, m# o H% ^
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.6 ^. @# `1 t: Z+ u4 Q
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.+ N0 v3 E" w8 j2 a/ m" H2 l0 s
CUPnPImpl::StopAsyncFind停止设备查找.
) n3 N* T3 v5 {0 w0 }CUPnPImpl::DeletePorts删除端口映射. |
|