wjwwood / serial

Cross-platform, Serial Port library written in C++
http://wjwwood.github.com/serial/
MIT License
2.13k stars 1.04k forks source link

Incorrect error returned for c'tor on windows #127

Open fastworks opened 8 years ago

fastworks commented 8 years ago

in win.cc line 85 there is the following line: ss << "Unknown error opening the serial port: " << errno;

In fact the error code was returned from DWORD errno = GetLastError(); So the line should really read: ss << "Unknown error opening the serial port: " << errno;

Ultimately I think it's not a good variable name anyway given that errno is already defined. The proper method should probably call FormatMessage to get the correct error message from the serial driver anyway. I can submit a patch if people think this is a good idea.

fastworks commented 8 years ago

The following is functional although not really technically correct. It falls back to a big of an architectural problem because the IOException does not support a UNICODE error string of type wstring so the windows error has to be converted and may not work properly under foreign language versions of windows. I have also not taken into account any non-UNICODE implementations but this falls back to the old behaviour. I've also renamed errno_ to last_error to improve readability.

Someone with the right tools can probably generate a proper patch for this.

if (fd_ == INVALID_HANDLE_VALUE) { DWORD last_error = GetLastError(); stringstream ss; LPVOID lpMsgBuf=NULL; switch (last_error) { case ERROR_FILE_NOT_FOUND: // Use this->getPort to convert to a std::string ss << "Specified port, " << this->getPort() << ", does not exist."; THROW (IOException, ss.str().c_str()); default: // get the text error specific to this serial driver

ifdef UNICODE

  DWORD result=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, last_error,
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL );
  if (result) {
    wstring err((WCHAR *)lpMsgBuf,(unsigned int)result);
    string errstr(err.begin(),err.end());
    ss << "Unknown error opening the serial port: " << errstr;
    THROW (IOException, ss.str().c_str());
  }
  else {
    ss << "Unknown error opening the serial port: " << last_error;
    THROW (IOException, ss.str().c_str());
  }

else

  ss << "Unknown error opening the serial port: " << last_error;
  THROW (IOException, ss.str().c_str());

endif

}

}