1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: MSW implementation of network/dialup classes and functions
4 // Author: Vadim Zeitlin
8 // Copyright: (c) Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // for compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
27 // these functions require Win32
28 #if defined(__WIN16__) && wxUSE_DIALUP_MANAGER
29 #undef wxUSE_DIALUP_MANAGER
30 #define wxUSE_DIALUP_MANAGER 0
31 #endif // wxUSE_DIALUP_MANAGER && Win16
33 #if wxUSE_DIALUP_MANAGER
39 #include "wx/dynlib.h"
46 #include "wx/msw/private.h"
48 // ----------------------------------------------------------------------------
50 // ----------------------------------------------------------------------------
52 // this message is sent by the secondary thread when RAS status changes
53 #define wxWM_RAS_STATUS_CHANGED (WM_USER + 10010)
55 // ----------------------------------------------------------------------------
57 // ----------------------------------------------------------------------------
59 // the signatures of RAS functions: all this is quite heavy, but we must do it
60 // to allow running wxWin programs on machine which don't have RAS installed
61 // (this does exist) - if we link with rasapi32.lib, the program will fail on
62 // startup because of the missing DLL...
65 typedef DWORD (* RASDIAL
)( LPRASDIALEXTENSIONS
, LPCSTR
, LPRASDIALPARAMSA
, DWORD
, LPVOID
, LPHRASCONN
);
66 typedef DWORD (* RASENUMCONNECTIONS
)( LPRASCONNA
, LPDWORD
, LPDWORD
);
67 typedef DWORD (* RASENUMENTRIES
)( LPCSTR
, LPCSTR
, LPRASENTRYNAMEA
, LPDWORD
, LPDWORD
);
68 typedef DWORD (* RASGETCONNECTSTATUS
)( HRASCONN
, LPRASCONNSTATUSA
);
69 typedef DWORD (* RASGETERRORSTRING
)( UINT
, LPSTR
, DWORD
);
70 typedef DWORD (* RASHANGUP
)( HRASCONN
);
71 typedef DWORD (* RASGETPROJECTIONINFO
)( HRASCONN
, RASPROJECTION
, LPVOID
, LPDWORD
);
72 typedef DWORD (* RASCREATEPHONEBOOKENTRY
)( HWND
, LPCSTR
);
73 typedef DWORD (* RASEDITPHONEBOOKENTRY
)( HWND
, LPCSTR
, LPCSTR
);
74 typedef DWORD (* RASSETENTRYDIALPARAMS
)( LPCSTR
, LPRASDIALPARAMSA
, BOOL
);
75 typedef DWORD (* RASGETENTRYDIALPARAMS
)( LPCSTR
, LPRASDIALPARAMSA
, LPBOOL
);
76 typedef DWORD (* RASENUMDEVICES
)( LPRASDEVINFOA
, LPDWORD
, LPDWORD
);
77 typedef DWORD (* RASGETCOUNTRYINFO
)( LPRASCTRYINFOA
, LPDWORD
);
78 typedef DWORD (* RASGETENTRYPROPERTIES
)( LPCSTR
, LPCSTR
, LPRASENTRYA
, LPDWORD
, LPBYTE
, LPDWORD
);
79 typedef DWORD (* RASSETENTRYPROPERTIES
)( LPCSTR
, LPCSTR
, LPRASENTRYA
, DWORD
, LPBYTE
, DWORD
);
80 typedef DWORD (* RASRENAMEENTRY
)( LPCSTR
, LPCSTR
, LPCSTR
);
81 typedef DWORD (* RASDELETEENTRY
)( LPCSTR
, LPCSTR
);
82 typedef DWORD (* RASVALIDATEENTRYNAME
)( LPCSTR
, LPCSTR
);
83 typedef DWORD (* RASCONNECTIONNOTIFICATION
)( HRASCONN
, HANDLE
, DWORD
);
85 static const char gs_funcSuffix
= 'A';
87 typedef DWORD (* RASDIAL
)( LPRASDIALEXTENSIONS
, LPCWSTR
, LPRASDIALPARAMSW
, DWORD
, LPVOID
, LPHRASCONN
);
88 typedef DWORD (* RASENUMCONNECTIONS
)( LPRASCONNW
, LPDWORD
, LPDWORD
);
89 typedef DWORD (* RASENUMENTRIES
)( LPCWSTR
, LPCWSTR
, LPRASENTRYNAMEW
, LPDWORD
, LPDWORD
);
90 typedef DWORD (* RASGETCONNECTSTATUS
)( HRASCONN
, LPRASCONNSTATUSW
);
91 typedef DWORD (* RASGETERRORSTRING
)( UINT
, LPWSTR
, DWORD
);
92 typedef DWORD (* RASHANGUP
)( HRASCONN
);
93 typedef DWORD (* RASGETPROJECTIONINFO
)( HRASCONN
, RASPROJECTION
, LPVOID
, LPDWORD
);
94 typedef DWORD (* RASCREATEPHONEBOOKENTRY
)( HWND
, LPCWSTR
);
95 typedef DWORD (* RASEDITPHONEBOOKENTRY
)( HWND
, LPCWSTR
, LPCWSTR
);
96 typedef DWORD (* RASSETENTRYDIALPARAMS
)( LPCWSTR
, LPRASDIALPARAMSW
, BOOL
);
97 typedef DWORD (* RASGETENTRYDIALPARAMS
)( LPCWSTR
, LPRASDIALPARAMSW
, LPBOOL
);
98 typedef DWORD (* RASENUMDEVICES
)( LPRASDEVINFOW
, LPDWORD
, LPDWORD
);
99 typedef DWORD (* RASGETCOUNTRYINFO
)( LPRASCTRYINFOW
, LPDWORD
);
100 typedef DWORD (* RASGETENTRYPROPERTIES
)( LPCWSTR
, LPCWSTR
, LPRASENTRYW
, LPDWORD
, LPBYTE
, LPDWORD
);
101 typedef DWORD (* RASSETENTRYPROPERTIES
)( LPCWSTR
, LPCWSTR
, LPRASENTRYW
, DWORD
, LPBYTE
, DWORD
);
102 typedef DWORD (* RASRENAMEENTRY
)( LPCWSTR
, LPCWSTR
, LPCWSTR
);
103 typedef DWORD (* RASDELETEENTRY
)( LPCWSTR
, LPCWSTR
);
104 typedef DWORD (* RASVALIDATEENTRYNAME
)( LPCWSTR
, LPCWSTR
);
105 typedef DWORD (* RASCONNECTIONNOTIFICATION
)( HRASCONN
, HANDLE
, DWORD
);
107 static const char gs_funcSuffix
= 'W';
108 #endif // ASCII/Unicode
110 // structure passed to the secondary thread
111 struct wxRasThreadData
116 hEventRas
= hEventQuit
= INVALID_HANDLE_VALUE
;
117 dialUpManager
= NULL
;
120 HWND hWnd
; // window to send notifications to
121 HANDLE hEventRas
, // event which RAS signals when status changes
122 hEventQuit
; // event which we signal when we terminate
124 class WXDLLEXPORT wxDialUpManagerMSW
*dialUpManager
; // the owner
127 // ----------------------------------------------------------------------------
128 // wxDialUpManager class for MSW
129 // ----------------------------------------------------------------------------
131 class WXDLLEXPORT wxDialUpManagerMSW
: public wxDialUpManager
135 wxDialUpManagerMSW();
136 virtual ~wxDialUpManagerMSW();
138 // implement base class pure virtuals
139 virtual bool IsOk() const;
140 virtual bool Dial(const wxString
& nameOfISP
,
141 const wxString
& username
,
142 const wxString
& password
);
143 virtual bool HangUp();
144 virtual bool IsOnline();
145 virtual void SetOnlineStatus(bool isOnline
= TRUE
);
146 virtual bool EnableAutoCheckOnlineStatus(size_t nSeconds
);
147 virtual void DisableAutoCheckOnlineStatus();
148 virtual void SetWellKnownHost(const wxString
& hostname
);
151 void CheckRasStatus(bool firstTime
= FALSE
);
153 // for wxRasStatusWindowProc
154 void OnConnectStatusChange();
157 // return the error string for the given RAS error code
158 wxString
GetErrorString(DWORD error
);
160 // find the (first) handle of the active connection
161 HRASCONN
FindActiveConnection();
163 // notify the application about status change
164 void NotifyApp(bool connected
) const;
166 // destroy the thread data and the thread itself
167 void CleanUpThreadData();
169 // timer used for polling RAS status
170 class RasTimer
: public wxTimer
173 RasTimer(wxDialUpManagerMSW
*dialUpManager
)
174 { m_dialUpManager
= dialUpManager
; }
176 virtual void Notify() { m_dialUpManager
->CheckRasStatus(); }
179 wxDialUpManagerMSW
*m_dialUpManager
;
180 } m_timerStatusPolling
;
182 // thread handle for the thread sitting on connection change event
185 // data used by this thread and our hidden window to send messages between
187 wxRasThreadData m_data
;
189 // the handle of the connection we initiated or 0 if none
190 static HRASCONN ms_hRasConnection
;
192 // the use count of rasapi32.dll
193 static int ms_nDllCount
;
195 // the handle of rasapi32.dll when it's loaded
196 static wxDllType ms_dllRas
;
198 // the pointers to RAS functions
199 static RASDIAL ms_pfnRasDial
;
200 static RASENUMCONNECTIONS ms_pfnRasEnumConnections
;
201 static RASENUMENTRIES ms_pfnRasEnumEntries
;
202 static RASGETCONNECTSTATUS ms_pfnRasGetConnectStatus
;
203 static RASGETERRORSTRING ms_pfnRasGetErrorString
;
204 static RASHANGUP ms_pfnRasHangUp
;
205 static RASGETPROJECTIONINFO ms_pfnRasGetProjectionInfo
;
206 static RASCREATEPHONEBOOKENTRY ms_pfnRasCreatePhonebookEntry
;
207 static RASEDITPHONEBOOKENTRY ms_pfnRasEditPhonebookEntry
;
208 static RASSETENTRYDIALPARAMS ms_pfnRasSetEntryDialParams
;
209 static RASGETENTRYDIALPARAMS ms_pfnRasGetEntryDialParams
;
210 static RASENUMDEVICES ms_pfnRasEnumDevices
;
211 static RASGETCOUNTRYINFO ms_pfnRasGetCountryInfo
;
212 static RASGETENTRYPROPERTIES ms_pfnRasGetEntryProperties
;
213 static RASSETENTRYPROPERTIES ms_pfnRasSetEntryProperties
;
214 static RASRENAMEENTRY ms_pfnRasRenameEntry
;
215 static RASDELETEENTRY ms_pfnRasDeleteEntry
;
216 static RASVALIDATEENTRYNAME ms_pfnRasValidateEntryName
;
218 // this function is not supported by Win95
219 static RASCONNECTIONNOTIFICATION ms_pfnRasConnectionNotification
;
221 // if this flag is different from -1, it overrides IsOnline()
222 static int ms_userSpecifiedOnlineStatus
;
225 // ----------------------------------------------------------------------------
227 // ----------------------------------------------------------------------------
229 static LRESULT APIENTRY
wxRasStatusWindowProc(HWND hWnd
, UINT message
,
230 WPARAM wParam
, LPARAM lParam
);
232 static DWORD
wxRasMonitorThread(wxRasThreadData
*data
);
234 // ============================================================================
236 // ============================================================================
238 // ----------------------------------------------------------------------------
239 // init the static variables
240 // ----------------------------------------------------------------------------
242 wxDialUpManager
*wxDialUpManager::ms_dialUpManager
= NULL
;
244 HRASCONN
wxDialUpManagerMSW::ms_hRasConnection
= 0;
246 int wxDialUpManagerMSW::ms_nDllCount
= 0;
247 wxDllType
wxDialUpManagerMSW::ms_dllRas
= 0;
249 RASDIAL
wxDialUpManagerMSW::ms_pfnRasDial
= 0;
250 RASENUMCONNECTIONS
wxDialUpManagerMSW::ms_pfnRasEnumConnections
= 0;
251 RASENUMENTRIES
wxDialUpManagerMSW::ms_pfnRasEnumEntries
= 0;
252 RASGETCONNECTSTATUS
wxDialUpManagerMSW::ms_pfnRasGetConnectStatus
= 0;
253 RASGETERRORSTRING
wxDialUpManagerMSW::ms_pfnRasGetErrorString
= 0;
254 RASHANGUP
wxDialUpManagerMSW::ms_pfnRasHangUp
= 0;
255 RASGETPROJECTIONINFO
wxDialUpManagerMSW::ms_pfnRasGetProjectionInfo
= 0;
256 RASCREATEPHONEBOOKENTRY
wxDialUpManagerMSW::ms_pfnRasCreatePhonebookEntry
= 0;
257 RASEDITPHONEBOOKENTRY
wxDialUpManagerMSW::ms_pfnRasEditPhonebookEntry
= 0;
258 RASSETENTRYDIALPARAMS
wxDialUpManagerMSW::ms_pfnRasSetEntryDialParams
= 0;
259 RASGETENTRYDIALPARAMS
wxDialUpManagerMSW::ms_pfnRasGetEntryDialParams
= 0;
260 RASENUMDEVICES
wxDialUpManagerMSW::ms_pfnRasEnumDevices
= 0;
261 RASGETCOUNTRYINFO
wxDialUpManagerMSW::ms_pfnRasGetCountryInfo
= 0;
262 RASGETENTRYPROPERTIES
wxDialUpManagerMSW::ms_pfnRasGetEntryProperties
= 0;
263 RASSETENTRYPROPERTIES
wxDialUpManagerMSW::ms_pfnRasSetEntryProperties
= 0;
264 RASRENAMEENTRY
wxDialUpManagerMSW::ms_pfnRasRenameEntry
= 0;
265 RASDELETEENTRY
wxDialUpManagerMSW::ms_pfnRasDeleteEntry
= 0;
266 RASVALIDATEENTRYNAME
wxDialUpManagerMSW::ms_pfnRasValidateEntryName
= 0;
267 RASCONNECTIONNOTIFICATION
wxDialUpManagerMSW::ms_pfnRasConnectionNotification
= 0;
269 int wxDialUpManagerMSW::ms_userSpecifiedOnlineStatus
= -1;
271 // ----------------------------------------------------------------------------
272 // ctor and dtor: the dynamic linking happens here
273 // ----------------------------------------------------------------------------
275 // the static creator function is implemented here
276 wxDialUpManager
*wxDialUpManager::Create()
278 return new wxDialUpManagerMSW
;
282 // warning about "'this' : used in base member initializer list" - so what?
283 #pragma warning(disable:4355)
286 wxDialUpManagerMSW::wxDialUpManagerMSW()
287 : m_timerStatusPolling(this)
289 if ( !ms_nDllCount
++ )
291 // load the RAS library
292 ms_dllRas
= wxDllLoader::LoadLibrary("RASAPI32");
295 wxLogError(_("Dial up functions are unavailable because the "
296 "remote access service (RAS) is not installed "
297 "on this machine. Please install it."));
301 // resolve the functions we need
303 // this will contain the name of the function we failed to resolve
305 const char *funcName
= NULL
;
307 // get the function from rasapi32.dll and abort if it's not found
308 #define RESOLVE_RAS_FUNCTION(type, name) \
309 ms_pfn##name = (type)wxDllLoader::GetSymbol(ms_dllRas, \
310 wxString(#name) + gs_funcSuffix); \
311 if ( !ms_pfn##name ) \
317 // a variant of above macro which doesn't abort if the function is
318 // not found in the DLL
319 #define RESOLVE_OPTIONAL_RAS_FUNCTION(type, name) \
320 ms_pfn##name = (type)wxDllLoader::GetSymbol(ms_dllRas, \
321 wxString(#name) + gs_funcSuffix);
323 RESOLVE_RAS_FUNCTION(RASDIAL
, RasDial
);
324 RESOLVE_RAS_FUNCTION(RASENUMCONNECTIONS
, RasEnumConnections
);
325 RESOLVE_RAS_FUNCTION(RASENUMENTRIES
, RasEnumEntries
);
326 RESOLVE_RAS_FUNCTION(RASGETCONNECTSTATUS
, RasGetConnectStatus
);
327 RESOLVE_RAS_FUNCTION(RASGETERRORSTRING
, RasGetErrorString
);
328 RESOLVE_RAS_FUNCTION(RASHANGUP
, RasHangUp
);
329 RESOLVE_RAS_FUNCTION(RASGETPROJECTIONINFO
, RasGetProjectionInfo
);
330 RESOLVE_RAS_FUNCTION(RASCREATEPHONEBOOKENTRY
, RasCreatePhonebookEntry
);
331 RESOLVE_RAS_FUNCTION(RASEDITPHONEBOOKENTRY
, RasEditPhonebookEntry
);
332 RESOLVE_RAS_FUNCTION(RASSETENTRYDIALPARAMS
, RasSetEntryDialParams
);
333 RESOLVE_RAS_FUNCTION(RASGETENTRYDIALPARAMS
, RasGetEntryDialParams
);
334 RESOLVE_RAS_FUNCTION(RASENUMDEVICES
, RasEnumDevices
);
335 RESOLVE_RAS_FUNCTION(RASGETCOUNTRYINFO
, RasGetCountryInfo
);
336 RESOLVE_RAS_FUNCTION(RASGETENTRYPROPERTIES
, RasGetEntryProperties
);
337 RESOLVE_RAS_FUNCTION(RASSETENTRYPROPERTIES
, RasSetEntryProperties
);
338 RESOLVE_RAS_FUNCTION(RASRENAMEENTRY
, RasRenameEntry
);
339 RESOLVE_RAS_FUNCTION(RASDELETEENTRY
, RasDeleteEntry
);
340 RESOLVE_RAS_FUNCTION(RASVALIDATEENTRYNAME
, RasValidateEntryName
);
342 RESOLVE_OPTIONAL_RAS_FUNCTION(RASCONNECTIONNOTIFICATION
, RasConnectionNotification
);
344 // keep your preprocessor name space clean
345 #undef RESOLVE_RAS_FUNCTION
346 #undef RESOLVE_OPTIONAL_RAS_FUNCTION
351 wxLogError(_("The version of remote access service (RAS) "
352 "installed on this machine is too old, please "
353 "upgrade (the following required function is "
354 "missing: %s)."), funcName
);
356 wxDllLoader::UnloadLibrary(ms_dllRas
);
362 // initialize our data
365 // enable auto check by default
366 EnableAutoCheckOnlineStatus(0);
369 wxDialUpManagerMSW::~wxDialUpManagerMSW()
373 if ( !--ms_nDllCount
)
375 // unload the RAS library
376 wxDllLoader::UnloadLibrary(ms_dllRas
);
381 // ----------------------------------------------------------------------------
383 // ----------------------------------------------------------------------------
385 wxString
wxDialUpManagerMSW::GetErrorString(DWORD error
)
387 wxCHECK_MSG( IsOk(), "", _T("using uninitialized wxDialUpManager") );
389 wxChar buffer
[512]; // this should be more than enough according to MS docs
390 DWORD dwRet
= ms_pfnRasGetErrorString(error
, buffer
, WXSIZEOF(buffer
));
393 case ERROR_INVALID_PARAMETER
:
394 // this was a standard Win32 error probably
395 return wxString(wxSysErrorMsg(error
));
399 wxLogSysError(dwRet
, _("Failed to retrieve text of RAS "
403 msg
.Printf(_("unknown error (error code %08x)."), error
);
408 // we want the error message to start from a lower case letter
409 buffer
[0] = wxTolower(buffer
[0]);
411 return wxString(buffer
);
415 HRASCONN
wxDialUpManagerMSW::FindActiveConnection()
417 wxCHECK_MSG( IsOk(), 0, _T("using uninitialized wxDialUpManager") );
419 // enumerate connections
420 DWORD cbBuf
= sizeof(RASCONN
);
421 LPRASCONN lpRasConn
= (LPRASCONN
)malloc(cbBuf
);
428 lpRasConn
->dwSize
= sizeof(RASCONN
);
430 DWORD nConnections
= 0;
431 DWORD dwRet
= ERROR_BUFFER_TOO_SMALL
;
433 while ( dwRet
== ERROR_BUFFER_TOO_SMALL
)
435 dwRet
= ms_pfnRasEnumConnections(lpRasConn
, &cbBuf
, &nConnections
);
437 if ( dwRet
== ERROR_BUFFER_TOO_SMALL
)
439 LPRASCONN lpRasConnOld
= lpRasConn
;
440 lpRasConn
= (LPRASCONN
)realloc(lpRasConn
, cbBuf
);
449 else if ( dwRet
== 0 )
457 wxLogError(_("Cannot find active dialup connection: %s"),
458 GetErrorString(dwRet
));
465 switch ( nConnections
)
473 // more than 1 connection - we don't know what to do with this
474 // case, so give a warning but continue (taking the first
475 // connection) - the warning is really needed because this function
476 // is used, for example, to select the connection to hang up and so
477 // we may hang up the wrong connection here...
478 wxLogWarning(_("Several active dialup connections found, "
479 "choosing one randomly."));
483 // exactly 1 connection, great
484 hrasconn
= lpRasConn
->hrasconn
;
492 void wxDialUpManagerMSW::CleanUpThreadData()
496 if ( !SetEvent(m_data
.hEventQuit
) )
498 wxLogLastError("SetEvent(RasThreadQuit)");
501 CloseHandle(m_hThread
);
508 DestroyWindow(m_data
.hWnd
);
513 if ( m_data
.hEventQuit
)
515 CloseHandle(m_data
.hEventQuit
);
517 m_data
.hEventQuit
= 0;
520 if ( m_data
.hEventRas
)
522 CloseHandle(m_data
.hEventRas
);
524 m_data
.hEventRas
= 0;
528 // ----------------------------------------------------------------------------
530 // ----------------------------------------------------------------------------
532 void wxDialUpManagerMSW::CheckRasStatus(bool firstTime
)
534 static int s_connected
= -1;
536 // use int, not bool to compare with -1
537 int connected
= FindActiveConnection() != 0;
538 if ( connected
!= s_connected
)
540 if ( (s_connected
== -1) || firstTime
)
542 // it's the first time we're called, just update the flag
546 // notify the program
547 NotifyApp(connected
!= 0);
550 s_connected
= connected
;
554 void wxDialUpManagerMSW::NotifyApp(bool connected
) const
556 wxDialUpEvent
event(connected
);
557 (void)wxTheApp
->ProcessEvent(event
);
560 void wxDialUpManagerMSW::OnConnectStatusChange()
562 // we know that status changed, but we don't know whether we're connected
563 // or not - so find it out
564 NotifyApp(FindActiveConnection() != 0);
567 // ----------------------------------------------------------------------------
568 // implementation of wxDialUpManager functions
569 // ----------------------------------------------------------------------------
571 bool wxDialUpManagerMSW::IsOk() const
573 return ms_nDllCount
!= 0;
576 bool wxDialUpManagerMSW::Dial(const wxString
& nameOfISP
,
577 const wxString
& username
,
578 const wxString
& password
)
580 wxCHECK_MSG( IsOk(), FALSE
, _T("using uninitialized wxDialUpManager") );
582 RASDIALPARAMS rasDialParams
;
583 rasDialParams
.dwSize
= sizeof(rasDialParams
);
584 strncpy(rasDialParams
.szEntryName
, nameOfISP
, RAS_MaxEntryName
);
585 rasDialParams
.szPhoneNumber
[0] = '\0';
586 rasDialParams
.szCallbackNumber
[0] = '*';
587 rasDialParams
.szCallbackNumber
[0] = '\0';
589 rasDialParams
.szUserName
[0] = '\0';
590 rasDialParams
.szPassword
[0] = '\0';
591 rasDialParams
.szDomain
[0] = '*';
592 rasDialParams
.szDomain
[1] = '\0';
595 if ( wxGetOsVersion() == wxWINDOWS_NT
)
597 // first get the length
598 UINT nLen
= ::GetSystemDirectory(NULL
, 0);
601 if ( !::GetSystemDirectory(phoneBook
.GetWriteBuf(nLen
), nLen
) )
603 wxLogSysError(_("Cannot find the location of address book file"));
606 phoneBook
.UngetWriteBuf();
608 // this is the default phone book
609 phoneBook
<< "\\ras\\rasphone.pbk";
612 ms_hRasConnection
= 0;
613 DWORD dwRet
= ms_pfnRasDial
615 (LPRASDIALEXTENSIONS
)NULL
,
616 phoneBook
, // phone book file (NT only)
618 0, // ignored because of next entry
619 NULL
, // no notifications - synchronous operations
625 wxLogError(_("Failed to establish dialup connection: %s"),
626 GetErrorString(dwRet
));
634 bool wxDialUpManagerMSW::HangUp()
636 wxCHECK_MSG( IsOk(), FALSE
, _T("using uninitialized wxDialUpManager") );
638 // we may terminate either the connection we initiated or another one which
640 HRASCONN hRasConn
= ms_hRasConnection
? ms_hRasConnection
641 : FindActiveConnection();
645 wxLogError(_("Cannot hang up - no active dialup connection."));
650 DWORD dwRet
= ms_pfnRasHangUp(hRasConn
);
653 wxLogError(_("Failed to terminate the dialup connection: %s"),
654 GetErrorString(dwRet
));
660 bool wxDialUpManagerMSW::IsOnline()
662 wxCHECK_MSG( IsOk(), FALSE
, _T("using uninitialized wxDialUpManager") );
664 if ( ms_userSpecifiedOnlineStatus
!= -1 )
666 // user specified flag overrides our logic
667 return ms_userSpecifiedOnlineStatus
!= 0;
671 // return TRUE if there is at least one active connection
672 return FindActiveConnection() != 0;
676 void wxDialUpManagerMSW::SetOnlineStatus(bool isOnline
)
678 wxCHECK_RET( IsOk(), _T("using uninitialized wxDialUpManager") );
680 ms_userSpecifiedOnlineStatus
= isOnline
;
683 bool wxDialUpManagerMSW::EnableAutoCheckOnlineStatus(size_t nSeconds
)
685 wxCHECK_MSG( IsOk(), FALSE
, _T("using uninitialized wxDialUpManager") );
687 bool ok
= ms_pfnRasConnectionNotification
!= 0;
691 // we're running under NT 4.0, Windows 98 or later and can use
692 // RasConnectionNotification() to be notified by a secondary thread
694 // first, see if we don't have this thread already running
695 if ( m_hThread
!= 0 )
697 DWORD dwSuspendCount
= 2;
698 while ( dwSuspendCount
> 1 )
700 dwSuspendCount
= ResumeThread(m_hThread
);
701 if ( dwSuspendCount
== (DWORD
)-1 )
703 wxLogLastError("ResumeThread(RasThread)");
716 // create all the stuff we need to be notified about RAS connection
721 // first create an event to wait on
722 m_data
.hEventRas
= CreateEvent
724 NULL
, // security attribute (default)
725 FALSE
, // manual reset (not)
726 FALSE
, // initial state (not signaled)
729 if ( !m_data
.hEventRas
)
731 wxLogLastError("CreateEvent(RasStatus)");
739 // create the event we use to quit the thread
740 m_data
.hEventQuit
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
741 if ( !m_data
.hEventQuit
)
743 wxLogLastError("CreateEvent(RasThreadQuit)");
753 // create a hidden window to receive notification about connections
755 extern wxChar wxPanelClassName
[];
756 m_data
.hWnd
= ::CreateWindow(wxPanelClassName
, NULL
,
759 (HMENU
)NULL
, wxGetInstance(), 0);
762 wxLogLastError("CreateWindow(RasHiddenWindow)");
770 FARPROC windowProc
= MakeProcInstance
772 (FARPROC
)wxRasStatusWindowProc
,
776 ::SetWindowLong(m_data
.hWnd
, GWL_WNDPROC
, (LONG
) windowProc
);
781 // start the secondary thread
782 m_data
.dialUpManager
= this;
785 m_hThread
= CreateThread
789 (LPTHREAD_START_ROUTINE
)wxRasMonitorThread
,
797 wxLogLastError("CreateThread(RasStatusThread)");
805 // start receiving RAS notifications
806 DWORD dwRet
= ms_pfnRasConnectionNotification
808 (HRASCONN
)INVALID_HANDLE_VALUE
,
810 3 /* RASCN_Connection | RASCN_Disconnection */
815 wxLogDebug(_T("RasConnectionNotification() failed: %s"),
816 GetErrorString(dwRet
));
826 // we're running under Windows 95 and have to poll ourselves
827 // (or, alternatively, the code above for NT/98 failed)
828 CheckRasStatus(TRUE
/* first time */);
829 m_timerStatusPolling
.Stop();
835 m_timerStatusPolling
.Start(nSeconds
* 1000);
840 void wxDialUpManagerMSW::DisableAutoCheckOnlineStatus()
842 wxCHECK_RET( IsOk(), _T("using uninitialized wxDialUpManager") );
846 // we have running secondary thread, it's just enough to suspend it
847 if ( SuspendThread(m_hThread
) == (DWORD
)-1 )
849 wxLogLastError("SuspendThread(RasThread)");
854 // even simpler - just stop the timer
855 m_timerStatusPolling
.Stop();
859 void wxDialUpManagerMSW::SetWellKnownHost(const wxString
& WXUNUSED(hostname
))
861 wxCHECK_RET( IsOk(), _T("using uninitialized wxDialUpManager") );
863 // nothing to do - we don't use this
866 // ----------------------------------------------------------------------------
868 // ----------------------------------------------------------------------------
870 static DWORD
wxRasMonitorThread(wxRasThreadData
*data
)
873 handles
[0] = data
->hEventRas
;
874 handles
[1] = data
->hEventQuit
;
879 DWORD dwRet
= WaitForMultipleObjects(2, handles
, FALSE
, INFINITE
);
884 // RAS connection status changed
885 SendMessage(data
->hWnd
, wxWM_RAS_STATUS_CHANGED
,
889 case WAIT_OBJECT_0
+ 1:
894 wxLogLastError("WaitForMultipleObjects(RasMonitor)");
902 static LRESULT APIENTRY
wxRasStatusWindowProc(HWND hWnd
, UINT message
,
903 WPARAM wParam
, LPARAM lParam
)
905 if ( message
== wxWM_RAS_STATUS_CHANGED
)
907 wxRasThreadData
*data
= (wxRasThreadData
*)lParam
;
908 data
->dialUpManager
->OnConnectStatusChange();
914 #endif // wxUSE_DIALUP_MANAGER