|
|
楼主 |
发表于 2011-7-15 17:28:52
|
显示全部楼层
以下有关upnp的接口来自emule,
( k6 v$ u" X* ^# |9 F
, ], N) i! t% |+ X1 O9 P
z, |) Z% E* H6 T///////////////////////////////////////////
W1 t* C: l- H5 `( o//upnp的抽象接口类,只需调用这些接口即可实现端口映射功能.
! R0 w! L) r: K$ g, O1 Y$ k5 n" [' ~: z# o1 I6 ~
! w3 e- e$ t6 c4 W. h8 x#pragma once9 L: p/ @( D# B8 k) |' |
#include <exception>5 ~' \: c5 ^7 [9 D$ ]* {, ]
9 \) u4 R' ?0 M* D# c( @/ U
! ^8 I G8 K/ V- ]2 g) T2 D" I& _
enum TRISTATE{
/ b" ^* z# f/ |0 G( f4 H TRIS_FALSE,# Z6 G }& ~* j; h
TRIS_UNKNOWN,
0 y- q6 H' t! v* e& a8 k, B TRIS_TRUE5 c; D9 w: U+ n
};1 K" m' n( A+ x
' ]* ^) u1 }; F, i4 p
* u' ^; Z) E' [: j: O; V5 |0 b
enum UPNP_IMPLEMENTATION{# \3 S2 G8 R; ^2 @5 U8 F$ b
UPNP_IMPL_WINDOWSERVICE = 0,
* k- ~4 b; n; k1 z5 s5 I' C UPNP_IMPL_MINIUPNPLIB,& I0 F2 B$ M0 o
UPNP_IMPL_NONE /*last*/" h( N: q3 _1 u* s+ R7 x" |6 _6 z
};
2 {, X' W2 |6 | F5 b! T8 T. O. p h
$ b) D. U7 A& { i& L# m) |
" e% t8 o# M4 w/ s* H3 T
" i& K, R! o$ ^% C! c" V% y7 ~
6 p& m4 |7 Z- V7 E1 D! g5 e- uclass CUPnPImpl+ ]1 t: H; @* h) s+ j
{
) E) @- z* n: g' i' N% g+ K* [( [public:
( o. Z( v' Y' q4 y+ P& ] CUPnPImpl();
/ S$ ]7 _1 W2 ^, H4 }7 s2 X virtual ~CUPnPImpl();' K) ]% Y$ f; V2 j5 t! o$ Z
struct UPnPError : std::exception {};
9 D `3 [6 i4 h, U; D9 f enum {1 I8 J2 z$ v7 }3 p7 X" v
UPNP_OK,/ O1 t+ V+ t& y/ f: N2 V9 W% V
UPNP_FAILED,
$ l, v& Y3 u% o UPNP_TIMEOUT# |8 b% v/ K$ G$ c- S
};
+ c9 |: D8 }* d: f0 G/ W7 V8 y! L! M5 W$ I
' t l p2 Q1 W' ? d o virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) = 0;. ~1 r/ k: b! |
virtual bool CheckAndRefresh() = 0;
1 k4 d b3 B$ ~% U virtual void StopAsyncFind() = 0;
8 r3 y! B# ~% l5 \' F% n* m virtual void DeletePorts() = 0;; J0 `: X. j. y, v7 ~
virtual bool IsReady() = 0;
5 b7 {2 I0 h2 R8 o virtual int GetImplementationID() = 0;3 _9 ^4 f- Z' E& p6 @
0 J& f3 E! Z* \) E% {3 l void LateEnableWebServerPort(uint16 nPort); // Add Webserverport on already installed portmapping2 O' u+ X' Z- I' m& Y' o5 J
% y$ ]% C# G9 U5 m r+ K0 Q5 Q
1 R3 ]: `; u- k* x void SetMessageOnResult(HWND hWindow, UINT nMessageID);
% G2 r/ }" ^ V1 i. S0 |+ y TRISTATE ArePortsForwarded() const { return m_bUPnPPortsForwarded; }
* z E; Y$ ?, [! n+ F- ` uint16 GetUsedTCPPort() { return m_nTCPPort; }
6 `5 P4 J: ~- u4 E' F uint16 GetUsedUDPPort() { return m_nUDPPort; }
, ~* f+ _1 {" T8 n0 ~9 I" e: [/ f7 N3 @& y' H9 c0 o% z6 @) m: Y9 f
1 G0 F q. z7 n5 C
// Implementation
6 `1 P/ l4 {# ], _protected:/ F5 K8 Z( Y V# Q1 i( }
volatile TRISTATE m_bUPnPPortsForwarded;% u, }9 C: _3 {; ]
void SendResultMessage();
4 w) h, {1 q6 k& u1 L+ i uint16 m_nUDPPort;# B) |; E! h G* u( N: t
uint16 m_nTCPPort;
5 {4 y, F% `. c8 Q: L$ ~% S& ? uint16 m_nTCPWebPort;" C3 D; W+ H0 N( [4 h( f0 H) _
bool m_bCheckAndRefresh;
& Q. t! P) `9 `. d
0 [: n' e0 A, s+ X
8 S6 c5 C9 U* c) m8 ~private:! f! L; [; n# E! ?! Q5 @" q
HWND m_hResultMessageWindow;: Z7 H" |0 L5 k! o5 p
UINT m_nResultMessageID;# d# i; s% S8 y' u
! C; c* w! T3 T6 p }9 X
5 x$ y4 |8 c6 I/ O
};
' u$ f% ^( J/ t
6 P+ J, B5 _* ~- G q) D' T. u# f7 T8 V! E" n! U Q- O" X
// Dummy Implementation to be used when no other implementation is available
6 i! n8 I8 }" m) t1 a- Q3 |4 hclass CUPnPImplNone: public CUPnPImpl/ E! ^2 M; j; k1 E1 K5 x
{
; m9 p9 q! l. v# zpublic:1 j9 I$ f2 ?0 T; K6 b) l' Q
virtual void StartDiscovery(uint16, uint16, uint16) { ASSERT( false ); }
' r" k: \ F1 v8 E0 q6 m virtual bool CheckAndRefresh() { return false; }% i) P$ F2 k' D
virtual void StopAsyncFind() { }
/ h+ M1 z6 i+ x2 S4 t3 `+ T virtual void DeletePorts() { }) N0 o6 A7 g$ e3 X. r0 g
virtual bool IsReady() { return false; }* `1 U% Q, T3 u$ u9 s
virtual int GetImplementationID() { return UPNP_IMPL_NONE; }+ n8 m' `- u' w7 c$ T" \
};! b3 U5 }# V& e8 B+ {7 n0 v
% S% Q. B6 S. Q
" f j6 ] B/ @: K! A
///////////////////////////////////// |6 }9 {& c- c! P% j9 j p
//下面是使用windows操作系统自带的UPNP功能的子类
0 A# G$ p6 @1 k- A7 k; t# ~. Z3 X* E1 y' D3 J6 ?1 x' P- Z! c
3 C) q" S1 y9 E#pragma once' F: X/ ?/ y$ H
#pragma warning( disable: 4355 )
/ ?: v# K, q5 r
) H, c1 C# s8 ]7 y" ^& `& U8 e. s9 F c% t# H4 E# ]+ Q: }
#include "UPnPImpl.h" u$ E" }4 R; m- O8 ], H
#include <upnp.h>
! S7 |( Z" a, {* J9 N#include <iphlpapi.h>
4 F8 b3 @' z0 m; `/ c#include <comdef.h>6 e4 j- {5 U( t0 L: P r
#include <winsvc.h>
: }, A1 m8 |2 j
' g, c+ J" g& |9 J
3 h6 P5 P: C8 [) T( j7 r, }#include <vector>) b8 f* Z4 C3 R* _ j8 X
#include <exception>9 E3 ~, C, @$ O, P2 z1 t, }4 W( X
#include <functional>/ c% ~ R& h5 N1 X/ ]
( b3 Y6 i- a& a j; ^4 J7 c7 K5 z2 E( X, \
/ |+ u8 h0 t. _
0 Y$ o) v! ]9 }0 z1 D: x+ |3 ~% w' ptypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinder,&IID_IUPnPDeviceFinder> > FinderPointer;
k* E2 g2 K5 j* ^/ mtypedef _com_ptr_t<_com_IIID<IUPnPDevice,&IID_IUPnPDevice> > DevicePointer;" P7 [! @+ Q, E9 l. D3 [
typedef _com_ptr_t<_com_IIID<IUPnPService,&IID_IUPnPService> > ServicePointer;
9 Q: ^, N: Y( k9 V1 s+ D; wtypedef _com_ptr_t<_com_IIID<IUPnPDeviceFinderCallback,&IID_IUPnPDeviceFinderCallback> > DeviceFinderCallback;
* ]+ l7 y- m# o9 xtypedef _com_ptr_t<_com_IIID<IUPnPServiceCallback,&IID_IUPnPServiceCallback> > ServiceCallback;' r; ^* A, ~* A+ g9 x
typedef _com_ptr_t<_com_IIID<IEnumUnknown,&IID_IEnumUnknown> > EnumUnknownPtr;( b+ }0 t" C5 ]' C' M6 P
typedef _com_ptr_t<_com_IIID<IUnknown,&IID_IUnknown> > UnknownPtr;0 p1 N/ v/ k# f2 q, \
9 P8 v$ g% z! H0 x) R- ?+ X9 U
. Y: U; C9 c `# \! a v F+ C
typedef DWORD (WINAPI* TGetBestInterface) (& i! u$ j5 w9 B( d, _
IPAddr dwDestAddr,
3 L* k4 }, c6 h+ E% `8 r PDWORD pdwBestIfIndex# s! `5 K. {5 P% Z& O
);
1 Z( P, j. D( n4 v4 V3 y# H, D. Q$ [) h3 m j8 S) G
8 e' R. ^$ K8 I. Mtypedef DWORD (WINAPI* TGetIpAddrTable) (
9 M' r0 j9 Z/ S) m$ \% A* q) F PMIB_IPADDRTABLE pIpAddrTable,
- |" g5 {; h* r6 ] PULONG pdwSize,
6 k* u! P' n+ ` BOOL bOrder
% t3 G, i+ d6 o* D( ^);# M& H; l m) ?7 o$ \( }+ v
. y! M8 \- u1 J R# g/ l
9 V* P. l; e- o$ r+ h9 V: z
typedef DWORD (WINAPI* TGetIfEntry) (
' ^8 ?) y/ G5 U: @4 { PMIB_IFROW pIfRow
" R: A0 V0 K% B1 W8 v);$ ]. m; {1 r9 c
( ?3 W$ f- u9 J: s/ U; M0 W! J
) K2 H3 r& O$ \CString translateUPnPResult(HRESULT hr);
! v o y8 @9 E; B yHRESULT UPnPMessage(HRESULT hr);
' g' ^' V/ ^- G8 h b
& {7 W/ [3 Z* Y/ }+ ~8 _7 k- n+ u
class CUPnPImplWinServ: public CUPnPImpl
5 p7 `- k, _/ ]2 U5 O- |! R: ~) M{
5 {4 W; r4 J( b friend class CDeviceFinderCallback;
2 l& B- ^; O* N) \8 E! J$ V friend class CServiceCallback;4 Q+ r' g8 S2 `% H1 X
// Construction
$ u$ p/ a3 E$ U8 jpublic:
/ f7 @4 r2 D2 B virtual ~CUPnPImplWinServ();9 C$ r) x+ G% f8 r9 C! ?: M$ n
CUPnPImplWinServ();$ s) _, E! a6 N& p. v# S7 [0 c1 L
/ v" X2 |# _, R4 O$ l2 ^+ A O. T
8 d- w% w7 N( ]: H% K, P/ A+ n virtual void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { StartDiscovery(nTCPPort, nUDPPort, nTCPWebPort, false); }# M v$ v8 f( m
virtual void StopAsyncFind();
% t9 F' `9 S$ j6 p, I; n% ^1 m virtual void DeletePorts();
8 T! O7 k. @0 @9 H+ L virtual bool IsReady();0 _- I+ {" n' z+ ]# X6 I7 ~4 g
virtual int GetImplementationID() { return UPNP_IMPL_WINDOWSERVICE; }
4 B2 a' S2 A7 m5 h8 R% J _! S9 z9 Y/ p* n6 k/ L* z
& A0 D4 ?% K7 \9 x2 y' h; O // No Support for Refreshing on this (fallback) implementation yet - in many cases where it would be needed (router reset etc)8 u D1 W& H M+ @6 k* U
// the windows side of the implementation tends to get bugged untill reboot anyway. Still might get added later# Z4 O/ C: |' z- j* D/ }8 J9 U3 i
virtual bool CheckAndRefresh() { return false; };
8 S" v9 c: m+ J( @ d- q
6 o8 J0 y+ }2 D, f& u% M$ V% W8 ^, H7 t k2 q. }/ ?! E
protected:
& P0 s" A8 @1 T( H* p& R void StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort, bool bSecondTry);- {; `$ j+ p4 y
void AddDevice(DevicePointer pDevice, bool bAddChilds, int nLevel = 0);3 h: c0 ?+ m# p! M6 L
void RemoveDevice(CComBSTR bsUDN);
! K$ V+ D; `! b5 ]$ l% ?1 B bool OnSearchComplete();' J9 s! O X9 @0 R8 ^ S
void Init();0 `. b5 A+ m! ~7 p! @8 m
0 z9 H0 T+ A9 h8 C8 u! \
) r" H& X( @& [/ ^* [& V& [6 `
inline bool IsAsyncFindRunning()
( [7 F2 }+ f4 I3 {! Y4 o6 ^ {
+ [/ K y0 [2 f" v- t! F if ( m_pDeviceFinder != NULL && m_bAsyncFindRunning && GetTickCount() - m_tLastEvent > 10000 )6 P2 R' u; X% K/ l+ ]
{* f( s% m. E: A5 _8 i: o4 s
m_pDeviceFinder->CancelAsyncFind( m_nAsyncFindHandle );
w) }$ a1 |5 O m_bAsyncFindRunning = false;
; l9 Z9 z* J4 f( K3 |/ } }, s& C& y, N" Z' v8 \4 g5 a- s
MSG msg;. d2 g2 A) y) p) i. b V3 h
while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )4 Z' l5 C5 K4 D9 b
{
: T7 X8 v6 ? Y2 ] ~; } TranslateMessage( &msg );9 p$ i+ z( M# }* e2 Z6 y
DispatchMessage( &msg );
; A0 j, o0 z" ^3 {" d }. Y2 G! g5 t0 n/ G# ?
return m_bAsyncFindRunning;
' h( v- _2 X( W% R* _! `# {7 G6 |( L }
" n+ y4 }1 \0 |. U+ F2 k4 d a8 c& }; K3 V: H# f- ^
: g. t- k: c( |% z
TRISTATE m_bUPnPDeviceConnected;( t' z" i" T+ Z: t& u/ `4 C
: b" D; \2 n& e+ W d( U& A
$ E0 _/ m( K0 g+ @3 U; T9 g// Implementation5 f3 g3 ^* O/ T( Z p6 J
// API functions
( R6 q/ |: d4 a% J" W; [ SC_HANDLE (WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD);) |1 ?" n' N) A) d- I/ W! e9 {8 E4 \- M
SC_HANDLE (WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD);2 a) }. D! t" m& a
BOOL (WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD);
6 y B$ }0 c4 n5 |) k7 m6 Z8 l BOOL (WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE);( I8 ]6 B: e9 I; ?
BOOL (WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*);
. p( t3 [) ]9 i4 j! p' y0 q9 h BOOL (WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
$ {4 }, h& I D1 I7 Y9 v4 N" P T7 D4 W# \% ?
2 p: L, I7 I$ C2 j: F
TGetBestInterface m_pfGetBestInterface;! H/ ~" q O* ~
TGetIpAddrTable m_pfGetIpAddrTable;4 {! ]' J( ^* A) U7 O0 }. S W% c5 i: m
TGetIfEntry m_pfGetIfEntry;
7 _8 r& |7 I k6 u
; |+ Q* o' i+ k% C; ?! h3 K! }) _1 C; Q7 A. V D! F
static FinderPointer CreateFinderInstance();
* J: [# y; K8 y4 m: R5 L struct FindDevice : std::unary_function< DevicePointer, bool >
% } R& p4 E3 i6 y9 E$ K$ }2 S {% F; U* ~0 L2 h
FindDevice(const CComBSTR& udn) : m_udn( udn ) {} a4 ?4 W I5 N2 B$ P
result_type operator()(argument_type device) const
0 Y0 i/ _- L: N7 @2 @6 y/ s {3 S1 [9 k* y3 ^$ Q+ ^: F
CComBSTR deviceName;( r$ A3 [1 @. v. l- ^. c" F; M9 E3 F6 h
HRESULT hr = device->get_UniqueDeviceName( &deviceName );
+ R" q0 X4 x/ ~- U0 M7 @$ L+ z+ Y( |1 G+ c6 n
6 Y& p0 S) |9 _) f9 J* D if ( FAILED( hr ) )( X+ X6 q! j" i9 D. G0 y) b
return UPnPMessage( hr ), false;
7 U% c" Q8 D5 R3 z/ f' m8 L) O3 H: M; c7 O5 V# ?
2 o' z( p# G8 d6 l* h+ S* l& O
return wcscmp( deviceName.m_str, m_udn ) == 0;6 \/ J. M; f% q F" z! i- L
}
- |6 ?; f" Q9 r* C% \% W6 z CComBSTR m_udn;+ {# N+ q ^6 a4 l" H7 H
};" `* F9 w. d- K
/ S- _6 h" \. v! k. I) f& o void ProcessAsyncFind(CComBSTR bsSearchType);: P2 g4 r; A. ]6 q
HRESULT GetDeviceServices(DevicePointer pDevice);
! G/ f7 q8 z5 P# g( i6 {3 ?/ `+ G void StartPortMapping();+ e0 s7 [' ~5 Z" N1 u
HRESULT MapPort(const ServicePointer& service);
) S4 {# X, |9 E& j void DeleteExistingPortMappings(ServicePointer pService);8 k4 c9 T: N2 d8 c& v% C) z" U7 ^
void CreatePortMappings(ServicePointer pService);
5 P& _: ?. \3 w: L( M [( Y- F/ U HRESULT SaveServices(EnumUnknownPtr pEU, const LONG nTotalItems);4 {2 o, h8 \* B2 |# A
HRESULT InvokeAction(ServicePointer pService, CComBSTR action, ( S% {/ S0 }; P$ U/ p) u/ [7 T
LPCTSTR pszInArgString, CString& strResult);# z/ `+ r4 R3 t
void StopUPnPService();
' l' l. I9 C: j4 j; X
. i# H3 m F" |2 K+ H" W: y2 A9 N1 Z( m2 _' m2 Z
// Utility functions
& @1 O7 t& L o: o9 ?7 I HRESULT CreateSafeArray(const VARTYPE vt, const ULONG nArgs, SAFEARRAY** ppsa);
$ _9 Q5 @9 r$ F3 A! Z INT_PTR CreateVarFromString(const CString& strArgs, VARIANT*** pppVars);
9 |9 L1 t$ t- j/ q INT_PTR GetStringFromOutArgs(const VARIANT* pvaOutArgs, CString& strArgs);7 Q4 y2 F- V/ ~1 X! [% V2 p
void DestroyVars(const INT_PTR nCount, VARIANT*** pppVars);
% P2 ]4 x+ a2 w1 [- @! h4 E HRESULT GetSafeArrayBounds(SAFEARRAY* psa, LONG* pLBound, LONG* pUBound);
~. i1 E: I+ A5 [# N3 ] HRESULT GetVariantElement(SAFEARRAY* psa, LONG pos, VARIANT* pvar);( M" Q( L2 ]4 x6 ~4 W3 `; ?2 u3 `; Q
CString GetLocalRoutableIP(ServicePointer pService);
" N9 n+ \: Y v
7 t4 i. U' `) B; [& a: D' d b$ D7 n, P3 i1 L s" M8 [
// Private members( [5 M H& r) J, \0 z- s
private:* q9 A5 w% l1 p% L- N
DWORD m_tLastEvent; // When the last event was received?
$ x7 F8 E' S, Y) {. S2 a std::vector< DevicePointer > m_pDevices;
8 ?$ z7 J0 v" G# e std::vector< ServicePointer > m_pServices;
6 u2 q, R& L1 K0 t) B FinderPointer m_pDeviceFinder; [7 U' c3 P4 x* g# T- Q
DeviceFinderCallback m_pDeviceFinderCallback;' A c! X" B+ h9 R6 Y* l
ServiceCallback m_pServiceCallback;: u. }& h, R. }+ H+ K& ]& y
8 R! h" j$ u0 A0 |, D
3 u- A2 @3 _; {7 e. c3 w2 @4 e& { LONG m_nAsyncFindHandle;# p3 q4 n' r, Y' z" _
bool m_bCOM;$ e' A! h1 V# u0 `! \
bool m_bPortIsFree;8 ^" S7 X* m- |/ Z8 Z @
CString m_sLocalIP;" t: T$ c- I. J& H
CString m_sExternalIP;
. `* b8 ?, y# G. X bool m_bADSL; // Is the device ADSL?* G$ S7 b z; p& Y9 [, A0 D
bool m_ADSLFailed; // Did port mapping failed for the ADSL device?6 g1 h% F+ z$ v, t
bool m_bInited;5 T8 ]: E1 z' y {$ n/ k& o9 N9 _
bool m_bAsyncFindRunning;
+ f) k. g6 w3 X8 o* F' d" H HMODULE m_hADVAPI32_DLL;% V4 C$ E2 ]4 Q$ t! S8 J
HMODULE m_hIPHLPAPI_DLL;: R0 @3 U* e) ^; E! h0 Q' f
bool m_bSecondTry;
; V) t2 W8 g: V( i3 Z# L- v9 n bool m_bServiceStartedByEmule;
7 I( H- H7 w3 f# E9 J2 c bool m_bDisableWANIPSetup;
2 W1 H4 f. Z5 o4 |7 n bool m_bDisableWANPPPSetup;
" H1 l% U1 A7 f/ M9 p" ?& ^4 Z, \' m9 o# U& S, Z
; V4 w" _4 G* h7 U* J, L
};
7 m/ _; T: F1 l, {0 R( f6 @, V6 u* ?/ O. z4 d8 U; ~
% p: M; r. q6 F1 ~: a) j2 f5 Z2 a
// DeviceFinder Callback
4 V6 ~' P0 O, U! Sclass CDeviceFinderCallback0 F* L2 Z. ]7 R) [5 F( k" V) |
: public IUPnPDeviceFinderCallback
3 E( ]8 h# Z7 F{9 k9 `. U: e @! N: C
public:' H/ d! J3 D4 J2 X$ P
CDeviceFinderCallback(CUPnPImplWinServ& instance)+ ~+ J# E/ ~1 j0 W+ X$ I
: m_instance( instance )
# v7 G- z) C2 m# S* B4 v { m_lRefCount = 0; }
{* V& G( ]6 `) x( j. O, g: B6 S% [/ Y6 u6 t2 x' X+ z9 u' y
- d; P; N2 R5 ]3 y) W# P0 k0 u" Q STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
# ?) C: _2 E7 C# @5 A STDMETHODIMP_(ULONG) AddRef();
# y% C$ h: ]! l6 Q STDMETHODIMP_(ULONG) Release();
+ M! P4 t! w% x4 C. Q9 g4 b% A5 Y+ d* S1 ]3 x, [% e9 F6 W8 e3 Q2 M
3 G9 p5 s9 I" u1 m, D+ G
// implementation) A* a3 D1 m" l p% l
private:
( x v2 m& k* E% L( @6 D HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice* pDevice);
* z/ T$ h7 _4 ^ HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN);
" i1 l4 A& c% l. @- z$ ^ HRESULT __stdcall SearchComplete(LONG nFindData); S0 Y8 M' V! o4 w: w6 Q3 L6 b/ k
% X. n$ f" l0 Z& b; I+ L# Q8 L s
& ]& n& |( j a, k6 b, `& Q) V- l
private:( s& s2 }& v0 H7 H: [
CUPnPImplWinServ& m_instance;( v4 _1 Y" o; T* @7 v1 x5 v+ A+ F1 Q
LONG m_lRefCount;* S! m. L f4 E8 A" }
};
" L6 D" ?0 ]! n- Q) L; f- G8 o9 }/ C5 u p: g; r' p9 D% i% H
) V3 j& |+ A+ q1 z; X' a/ c7 e3 ?5 w/ @// Service Callback 2 b- A7 p% _, H0 p
class CServiceCallback& K% t5 M9 o( l* N( [+ W
: public IUPnPServiceCallback* \" t C- c u1 {8 T3 g: U
{5 e% }1 Z; {8 @& W2 ]8 G; J
public: E6 m0 ]( ]/ X
CServiceCallback(CUPnPImplWinServ& instance)
8 [3 k- G7 _3 r- _8 i& ^' ]% w& Y : m_instance( instance ) t! i* \3 n: F/ K
{ m_lRefCount = 0; }" P' h; _ `* [& n* [! n6 A! p) v+ A
3 p8 q. n$ c2 C: i6 k1 E/ r
STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);3 t* V/ e' T5 F2 Q
STDMETHODIMP_(ULONG) AddRef();
6 h3 l8 h- k. F STDMETHODIMP_(ULONG) Release();& {. f+ }$ v6 p, u/ n8 n. y
2 D: E% Q+ w- T+ l! `) f
! Z# V% Q- W3 W g% \6 B/ B// implementation
& j4 q* y7 m/ I% W/ \$ n& |private:
4 N7 x% I3 ?% A9 z HRESULT __stdcall StateVariableChanged(IUPnPService* pService, LPCWSTR pszStateVarName, VARIANT varValue);
4 z3 L9 m# s) A* G- d) h HRESULT __stdcall ServiceInstanceDied(IUPnPService* pService);/ q! f, s1 g0 }0 N! n& g
. f5 G, \7 |2 c2 L- m! {3 J
+ a) J3 p- X, Iprivate:" h& v$ D) w8 n5 g3 ^
CUPnPImplWinServ& m_instance;8 j/ T% {* ^/ u* O2 [; _9 N9 C. s
LONG m_lRefCount;
1 M5 {2 X) f9 W1 P& H) ?- ?};) x+ z0 l) C4 }9 i. N p
1 J/ [" z( `- h& }0 d% x. j5 j, R5 y( u4 w2 y: |- k7 r
/////////////////////////////////////////////////2 u4 R( \& \5 |; {0 h, H5 n
4 K: H; ^$ m7 b0 g( H9 j
7 A( T1 T' B6 {% H使用时只需要使用抽象类的接口。) E' A$ l6 u k% H7 O& `, x0 T {' R
CUPnPImpl::SetMessageOnResult设置需要接受UPNP端口映射是否成功的窗口句柄和消息ID.6 v: m4 m$ U! y
CUPnPImpl::StartDiscovery将开启一个异步设备查找并进行端口映射,其参数为需要映射的内网端口.
% D& x( m1 i/ z4 e8 XCUPnPImpl::StopAsyncFind停止设备查找.& C4 u7 X K+ i. n; v5 J1 }
CUPnPImpl::DeletePorts删除端口映射. |
|