3 // (C) Copyright Seb Wills 2005
7 // Win32-specific socket input class
11 #include "..\Common\WinCommon.h"
15 #include "./SocketInput.h"
17 #include "../../Win32/resource.h" // Probably shouldn't be including a file outside DasherCore. This is needed purely for the resource strings (IDS_...) used in the error message titles
31 using namespace Dasher
;
35 // Track memory leaks on Windows to the line that new'd the memory
41 #define DEBUG_NEW new( _NORMAL_BLOCK, THIS_FILE, __LINE__ )
47 static char THIS_FILE
[] = __FILE__
;
55 CSocketInput::CSocketInput(CEventHandler
* pEventHandler
, CSettingsStore
* pSettingsStore
)
57 :CSocketInputBase(pEventHandler
, pSettingsStore
) {
61 allocatedConsole
= false;
65 // Although SetDebug is called in the constructore for CSocketInputBase, that invokes CSocketInputBase::SetDebug,
67 // and we need to invoke CSocketInput::SetDebug to bring up the debug messages window if debugging is enabled.
69 SetDebug(GetBoolParameter(BP_SOCKET_DEBUG
));
73 // Windows-specific initialisation of Winsock:
75 WORD wVersionRequested
;
81 wVersionRequested
= MAKEWORD( 2, 2 );
83 err
= WSAStartup( wVersionRequested
, &wsaData
);
89 WinLocalisation::GetResourceString(IDS_ERR_SOCKET_TITLE
, &ErrTitle
);
91 MessageBox(NULL
, _TEXT("Failed to initialize Winsock DLL"), ErrTitle
.c_str(), MB_OK
| MB_ICONEXCLAMATION
);
99 CSocketInput::~CSocketInput() {
109 bool CSocketInput::LaunchReaderThread() {
115 m_readerThreadHandle
= (HANDLE
) _beginthreadex(NULL
, // security attributes
117 0, // stack size (0 = use default)
119 ThreadLauncherStub
, // function to invoke
125 &threadId
); // receives thread ID
127 if(m_readerThreadHandle
== 0) {
129 ReportErrnoError("Error creating reader thread");
141 void CSocketInput::CancelReaderThread() {
143 // FIXME: this is ugly; should have a way of cleanly terminating the thread
145 // The thread will need to use select to check the socket input buffer
147 // (rather than just calling recv which blocks indefinitely) and monitor a pleaseStop
149 // variable or something. But this seems to work OK...
151 TerminateThread(m_readerThreadHandle
, 1);
157 void CSocketInput::ReportError(std::string s
) {
159 CString
msg(s
.c_str()); //FIXME: check what goes on here with encodings. Is s in UTF-8? Do we need to call mbstowcs or something on it?
163 WinLocalisation::GetResourceString(IDS_ERR_SOCKET_TITLE
, &ErrTitle
);
165 MessageBox(NULL
, msg
, ErrTitle
.c_str(), MB_OK
| MB_ICONEXCLAMATION
);
171 void CSocketInput::ReportErrnoError(std::string prefix
) {
173 CString
msg(prefix
.c_str());
175 //wchar_t *tmp = new wchar_t[mbstowcs(NULL, (const char *) prefix.c_str(), 1024)];
179 msg
+= _TEXT(": Errno reports '");
181 msg
+= _tcserror(errno
); // retrieve localised error message for the most recent socket error
185 msg2
.Format(_TEXT("'. WSAGetLastError returns %d."), WSAGetLastError());
193 WinLocalisation::GetResourceString(IDS_ERR_SOCKET_TITLE
, &ErrTitle
);
195 MessageBox(NULL
, msg
, ErrTitle
.c_str(), MB_OK
| MB_ICONEXCLAMATION
);
201 void CSocketInput::SetDebug(bool _debug
) {
202 if(_debug
&& !allocatedConsole
) {
204 freopen("conout$", "w", stderr
); // makes stderr go to the new console window (but not std::cerr, it seems!)
205 allocatedConsole
= true;
207 CSocketInputBase::SetDebug(_debug
);