Skip to content

Commit

Permalink
Split SystemException to handle Windows
Browse files Browse the repository at this point in the history
Windows has (at least) two error namespaces, both errno and
GetLastResult(). These overlap, so it is important we keep track of
which one we are dealing with.

To make things extra problematic, the BSD socket API normally uses
errno, but on Windows it has been mapped in to the GetLastResult()
namespace.

Try to keep better control of this by using separate classes for the
namespaces.
  • Loading branch information
CendioOssman committed Sep 10, 2024
1 parent 4f9aed1 commit 584d05b
Show file tree
Hide file tree
Showing 39 changed files with 184 additions and 167 deletions.
16 changes: 8 additions & 8 deletions common/os/Mutex.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Mutex::Mutex()
systemMutex = new pthread_mutex_t;
ret = pthread_mutex_init((pthread_mutex_t*)systemMutex, nullptr);
if (ret != 0)
throw rdr::SystemException("Failed to create mutex", ret);
throw rdr::PosixException("Failed to create mutex", ret);
#endif
}

Expand All @@ -67,7 +67,7 @@ void Mutex::lock()

ret = pthread_mutex_lock((pthread_mutex_t*)systemMutex);
if (ret != 0)
throw rdr::SystemException("Failed to lock mutex", ret);
throw rdr::PosixException("Failed to lock mutex", ret);
#endif
}

Expand All @@ -80,7 +80,7 @@ void Mutex::unlock()

ret = pthread_mutex_unlock((pthread_mutex_t*)systemMutex);
if (ret != 0)
throw rdr::SystemException("Failed to unlock mutex", ret);
throw rdr::PosixException("Failed to unlock mutex", ret);
#endif
}

Expand All @@ -97,7 +97,7 @@ Condition::Condition(Mutex* mutex_)
systemCondition = new pthread_cond_t;
ret = pthread_cond_init((pthread_cond_t*)systemCondition, nullptr);
if (ret != 0)
throw rdr::SystemException("Failed to create condition variable", ret);
throw rdr::PosixException("Failed to create condition variable", ret);
#endif
}

Expand All @@ -120,14 +120,14 @@ void Condition::wait()
(CRITICAL_SECTION*)mutex->systemMutex,
INFINITE);
if (!ret)
throw rdr::SystemException("Failed to wait on condition variable", GetLastError());
throw rdr::Win32Exception("Failed to wait on condition variable", GetLastError());
#else
int ret;

ret = pthread_cond_wait((pthread_cond_t*)systemCondition,
(pthread_mutex_t*)mutex->systemMutex);
if (ret != 0)
throw rdr::SystemException("Failed to wait on condition variable", ret);
throw rdr::PosixException("Failed to wait on condition variable", ret);
#endif
}

Expand All @@ -140,7 +140,7 @@ void Condition::signal()

ret = pthread_cond_signal((pthread_cond_t*)systemCondition);
if (ret != 0)
throw rdr::SystemException("Failed to signal condition variable", ret);
throw rdr::PosixException("Failed to signal condition variable", ret);
#endif
}

Expand All @@ -153,6 +153,6 @@ void Condition::broadcast()

ret = pthread_cond_broadcast((pthread_cond_t*)systemCondition);
if (ret != 0)
throw rdr::SystemException("Failed to broadcast condition variable", ret);
throw rdr::PosixException("Failed to broadcast condition variable", ret);
#endif
}
10 changes: 5 additions & 5 deletions common/os/Thread.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ void Thread::start()
#ifdef WIN32
*(HANDLE*)threadId = CreateThread(nullptr, 0, startRoutine, this, 0, nullptr);
if (*(HANDLE*)threadId == nullptr)
throw rdr::SystemException("Failed to create thread", GetLastError());
throw rdr::Win32Exception("Failed to create thread", GetLastError());
#else
int ret;
sigset_t all, old;
Expand All @@ -76,14 +76,14 @@ void Thread::start()
sigfillset(&all);
ret = pthread_sigmask(SIG_SETMASK, &all, &old);
if (ret != 0)
throw rdr::SystemException("Failed to mask signals", ret);
throw rdr::PosixException("Failed to mask signals", ret);

ret = pthread_create((pthread_t*)threadId, nullptr, startRoutine, this);

pthread_sigmask(SIG_SETMASK, &old, nullptr);

if (ret != 0)
throw rdr::SystemException("Failed to create thread", ret);
throw rdr::PosixException("Failed to create thread", ret);
#endif

running = true;
Expand All @@ -99,13 +99,13 @@ void Thread::wait()

ret = WaitForSingleObject(*(HANDLE*)threadId, INFINITE);
if (ret != WAIT_OBJECT_0)
throw rdr::SystemException("Failed to join thread", GetLastError());
throw rdr::Win32Exception("Failed to join thread", GetLastError());
#else
int ret;

ret = pthread_join(*(pthread_t*)threadId, nullptr);
if (ret != 0)
throw rdr::SystemException("Failed to join thread", ret);
throw rdr::PosixException("Failed to join thread", ret);
#endif
}

Expand Down
28 changes: 16 additions & 12 deletions common/rdr/Exception.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,23 @@ GAIException::GAIException(const char* s, int err_)
strncat(str_, ")", len-1-strlen(str_));
}

SystemException::SystemException(const char* s, int err_)
PosixException::PosixException(const char* s, int err_)
: Exception("%s", s), err(err_)
{
strncat(str_, ": ", len-1-strlen(str_));
strncat(str_, strerror(err), len-1-strlen(str_));
strncat(str_, " (", len-1-strlen(str_));
char buf[20];
sprintf(buf,"%d",err);
strncat(str_, buf, len-1-strlen(str_));
strncat(str_, ")", len-1-strlen(str_));
}

#ifdef WIN32
Win32Exception::Win32Exception(const char* s, unsigned err_)
: Exception("%s", s), err(err_)
{
strncat(str_, ": ", len-1-strlen(str_));
#ifdef _WIN32
wchar_t *currStr = new wchar_t[len-strlen(str_)];
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, err, 0, currStr, len-1-strlen(str_), nullptr);
Expand All @@ -92,18 +104,10 @@ SystemException::SystemException(const char* s, int err_)
if ((l >= 2) && (str_[l-2] == '\r') && (str_[l-1] == '\n'))
str_[l-2] = 0;

#else
strncat(str_, strerror(err), len-1-strlen(str_));
#endif
strncat(str_, " (", len-1-strlen(str_));
char buf[20];
#ifdef WIN32
if (err < 0)
sprintf(buf, "%x", err);
else
#endif
sprintf(buf,"%d",err);
sprintf(buf,"%d",err);
strncat(str_, buf, len-1-strlen(str_));
strncat(str_, ")", len-1-strlen(str_));
}

#endif
21 changes: 17 additions & 4 deletions common/rdr/Exception.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,27 @@ namespace rdr {
virtual const char* str() const { return str_; }
};

struct SystemException : public Exception {
struct PosixException : public Exception {
int err;
SystemException(const char* s, int err_);
PosixException(const char* s, int err_);
};

struct SocketException : public SystemException {
SocketException(const char* text, int err_) : SystemException(text, err_) {}
#ifdef WIN32
struct Win32Exception : public Exception {
unsigned err;
Win32Exception(const char* s, unsigned err_);
};
#endif

#ifdef WIN32
struct SocketException : public Win32Exception {
SocketException(const char* text, unsigned err_) : Win32Exception(text, err_) {}
};
#else
struct SocketException : public PosixException {
SocketException(const char* text, int err_) : PosixException(text, err_) {}
};
#endif

struct GAIException : public Exception {
int err;
Expand Down
4 changes: 2 additions & 2 deletions common/rdr/FileInStream.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ FileInStream::FileInStream(const char *fileName)
{
file = fopen(fileName, "rb");
if (!file)
throw SystemException("fopen", errno);
throw PosixException("fopen", errno);
}

FileInStream::~FileInStream(void) {
Expand All @@ -48,7 +48,7 @@ bool FileInStream::fillBuffer()
size_t n = fread((uint8_t*)end, 1, availSpace(), file);
if (n == 0) {
if (ferror(file))
throw SystemException("fread", errno);
throw PosixException("fread", errno);
if (feof(file))
throw EndOfStream();
return false;
Expand Down
6 changes: 3 additions & 3 deletions common/rdr/RandomStream.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,16 @@ bool RandomStream::fillBuffer() {
#ifdef RFB_HAVE_WINCRYPT
if (provider) {
if (!CryptGenRandom(provider, availSpace(), (uint8_t*)end))
throw rdr::SystemException("unable to CryptGenRandom", GetLastError());
throw rdr::Win32Exception("unable to CryptGenRandom", GetLastError());
end += availSpace();
} else {
#else
#ifndef WIN32
if (fp) {
size_t n = fread((uint8_t*)end, 1, availSpace(), fp);
if (n <= 0)
throw rdr::SystemException("reading /dev/urandom or /dev/random failed",
errno);
throw rdr::PosixException("reading /dev/urandom or /dev/random failed",
errno);
end += n;
} else {
#else
Expand Down
4 changes: 2 additions & 2 deletions common/rfb/SSecurityRSAAES.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ void SSecurityRSAAES::loadPrivateKey()
{
FILE* file = fopen(keyFile, "rb");
if (!file)
throw rdr::SystemException("failed to open key file", errno);
throw rdr::PosixException("failed to open key file", errno);
fseek(file, 0, SEEK_END);
size_t size = ftell(file);
if (size == 0 || size > MaxKeyFileSize) {
Expand All @@ -167,7 +167,7 @@ void SSecurityRSAAES::loadPrivateKey()
std::vector<uint8_t> data(size);
if (fread(data.data(), 1, data.size(), file) != size) {
fclose(file);
throw rdr::SystemException("failed to read key", errno);
throw rdr::PosixException("failed to read key", errno);
}
fclose(file);

Expand Down
6 changes: 3 additions & 3 deletions vncviewer/ServerDialog.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ void ServerDialog::loadServerHistory()
return;
}
std::string msg = format(_("Could not open \"%s\""), filepath);
throw rdr::SystemException(msg.c_str(), errno);
throw rdr::PosixException(msg.c_str(), errno);
}

int lineNr = 0;
Expand All @@ -375,7 +375,7 @@ void ServerDialog::loadServerHistory()
fclose(f);
std::string msg = format(_("Failed to read line %d in "
"file \"%s\""), lineNr, filepath);
throw rdr::SystemException(msg.c_str(), errno);
throw rdr::PosixException(msg.c_str(), errno);
}

int len = strlen(line);
Expand Down Expand Up @@ -431,7 +431,7 @@ void ServerDialog::saveServerHistory()
FILE* f = fopen(filepath, "w+");
if (!f) {
std::string msg = format(_("Could not open \"%s\""), filepath);
throw rdr::SystemException(msg.c_str(), errno);
throw rdr::PosixException(msg.c_str(), errno);
}

// Save the last X elements to the config file.
Expand Down
22 changes: 11 additions & 11 deletions vncviewer/Surface_Win32.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ void Surface::draw(int src_x, int src_y, int dst_x, int dst_y,

dc = CreateCompatibleDC(fl_gc);
if (!dc)
throw rdr::SystemException("CreateCompatibleDC", GetLastError());
throw rdr::Win32Exception("CreateCompatibleDC", GetLastError());

if (!SelectObject(dc, bitmap))
throw rdr::SystemException("SelectObject", GetLastError());
throw rdr::Win32Exception("SelectObject", GetLastError());

if (!BitBlt(fl_gc, dst_x, dst_y, dst_w, dst_h,
dc, src_x, src_y, SRCCOPY)) {
Expand All @@ -70,7 +70,7 @@ void Surface::draw(int src_x, int src_y, int dst_x, int dst_y,
// with it. For now, we've only seen this error and for this function
// so only ignore this combination.
if (GetLastError() != ERROR_INVALID_HANDLE)
throw rdr::SystemException("BitBlt", GetLastError());
throw rdr::Win32Exception("BitBlt", GetLastError());
}

DeleteDC(dc);
Expand All @@ -83,10 +83,10 @@ void Surface::draw(Surface* dst, int src_x, int src_y,

dstdc = CreateCompatibleDC(nullptr);
if (!dstdc)
throw rdr::SystemException("CreateCompatibleDC", GetLastError());
throw rdr::Win32Exception("CreateCompatibleDC", GetLastError());

if (!SelectObject(dstdc, dst->bitmap))
throw rdr::SystemException("SelectObject", GetLastError());
throw rdr::Win32Exception("SelectObject", GetLastError());

origdc = fl_gc;
fl_gc = dstdc;
Expand All @@ -113,15 +113,15 @@ void Surface::blend(Surface* dst, int src_x, int src_y,

dstdc = CreateCompatibleDC(nullptr);
if (!dstdc)
throw rdr::SystemException("CreateCompatibleDC", GetLastError());
throw rdr::Win32Exception("CreateCompatibleDC", GetLastError());
srcdc = CreateCompatibleDC(nullptr);
if (!srcdc)
throw rdr::SystemException("CreateCompatibleDC", GetLastError());
throw rdr::Win32Exception("CreateCompatibleDC", GetLastError());

if (!SelectObject(dstdc, dst->bitmap))
throw rdr::SystemException("SelectObject", GetLastError());
throw rdr::Win32Exception("SelectObject", GetLastError());
if (!SelectObject(srcdc, bitmap))
throw rdr::SystemException("SelectObject", GetLastError());
throw rdr::Win32Exception("SelectObject", GetLastError());

blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
Expand All @@ -136,7 +136,7 @@ void Surface::blend(Surface* dst, int src_x, int src_y,
// with it. For now, we've only seen this error and for this function
// so only ignore this combination.
if (GetLastError() != ERROR_INVALID_HANDLE)
throw rdr::SystemException("BitBlt", GetLastError());
throw rdr::Win32Exception("BitBlt", GetLastError());
}

DeleteDC(srcdc);
Expand All @@ -161,7 +161,7 @@ void Surface::alloc()
bitmap = CreateDIBSection(nullptr, (BITMAPINFO*)&bih,
DIB_RGB_COLORS, (void**)&data, nullptr, 0);
if (!bitmap)
throw rdr::SystemException("CreateDIBSection", GetLastError());
throw rdr::Win32Exception("CreateDIBSection", GetLastError());
}

void Surface::dealloc()
Expand Down
2 changes: 1 addition & 1 deletion vncviewer/UserDialog.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ void UserDialog::getUserPasswd(bool secure_, std::string* user,

fp = fopen(passwordFileName, "rb");
if (!fp)
throw rdr::SystemException(_("Opening password file failed"), errno);
throw rdr::PosixException(_("Opening password file failed"), errno);

obfPwd.resize(fread(obfPwd.data(), 1, obfPwd.size(), fp));
fclose(fp);
Expand Down
Loading

0 comments on commit 584d05b

Please sign in to comment.