From b99daadb05e14e85da6c5e905057e10fc27c0fcf Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 13 Jan 2023 12:47:48 +0100 Subject: [PATCH] Use std::string instead of CharArray Let's use a more common type instead of something homegrown. Should be more familiar to new developers. --- common/network/TcpSocket.cxx | 1 + common/rfb/CConnection.cxx | 4 +- common/rfb/CConnection.h | 5 +- common/rfb/CMakeLists.txt | 2 +- common/rfb/CSecurityRSAAES.cxx | 5 +- common/rfb/CSecurityTLS.cxx | 93 ++++++++++++++-------- common/rfb/Configuration.cxx | 2 +- common/rfb/Configuration.h | 12 +-- common/rfb/Congestion.cxx | 1 + common/rfb/KeyRemapper.cxx | 1 + common/rfb/SConnection.cxx | 9 +-- common/rfb/SConnection.h | 2 +- common/rfb/SSecurityRSAAES.cxx | 8 +- common/rfb/SSecurityVncAuth.cxx | 48 ++++++----- common/rfb/SSecurityVncAuth.h | 7 +- common/rfb/VNCSConnectionST.cxx | 13 +-- common/rfb/VNCSConnectionST.h | 6 +- common/rfb/VNCServerST.cxx | 12 +-- common/rfb/VNCServerST.h | 4 +- common/rfb/{Password.cxx => obfuscate.cxx} | 64 ++++++--------- common/rfb/{Password.h => obfuscate.h} | 32 +++----- common/rfb/util.cxx | 29 ++++++- common/rfb/util.h | 6 +- unix/tx/TXButton.h | 10 +-- unix/tx/TXLabel.h | 28 +++---- unix/vncpasswd/vncpasswd.cxx | 57 ++++++------- unix/x0vncserver/Geometry.cxx | 2 + unix/x0vncserver/Image.cxx | 1 + unix/xserver/hw/vnc/RFBGlue.cc | 1 + unix/xserver/hw/vnc/XserverDesktop.cc | 8 +- unix/xserver/hw/vnc/XserverDesktop.h | 4 +- vncviewer/ServerDialog.cxx | 1 + vncviewer/UserDialog.cxx | 9 +-- win/rfb_win32/CurrentUser.cxx | 4 +- win/rfb_win32/CurrentUser.h | 5 +- win/rfb_win32/Dialog.cxx | 6 +- win/rfb_win32/Dialog.h | 6 +- win/rfb_win32/LaunchProcess.cxx | 28 ++++--- win/rfb_win32/LaunchProcess.h | 8 +- win/rfb_win32/MsgBox.h | 13 ++- win/rfb_win32/MsgWindow.cxx | 10 +-- win/rfb_win32/MsgWindow.h | 8 +- win/rfb_win32/Registry.cxx | 1 + win/rfb_win32/Service.cxx | 21 ++--- win/rfb_win32/SocketManager.cxx | 1 + win/rfb_win32/Win32Util.cxx | 8 +- win/vncconfig/Authentication.h | 5 +- win/vncconfig/Connections.h | 34 ++++---- win/vncconfig/Legacy.cxx | 26 +++--- win/vncconfig/PasswordDialog.cxx | 13 ++- win/winvnc/AddNewClientDialog.h | 10 +-- win/winvnc/QueryConnectDialog.cxx | 13 ++- win/winvnc/QueryConnectDialog.h | 5 +- win/winvnc/STrayIcon.cxx | 13 ++- win/winvnc/STrayIcon.h | 2 +- win/winvnc/VNCServerService.cxx | 8 +- win/winvnc/VNCServerWin32.cxx | 9 +-- win/winvnc/winvnc.cxx | 22 ++--- 58 files changed, 391 insertions(+), 375 deletions(-) rename common/rfb/{Password.cxx => obfuscate.cxx} (57%) rename common/rfb/{Password.h => obfuscate.h} (59%) diff --git a/common/network/TcpSocket.cxx b/common/network/TcpSocket.cxx index 4feab0ae..87f2e757 100644 --- a/common/network/TcpSocket.cxx +++ b/common/network/TcpSocket.cxx @@ -41,6 +41,7 @@ #include #include #include +#include #ifdef WIN32 #include diff --git a/common/rfb/CConnection.cxx b/common/rfb/CConnection.cxx index 8e545b2f..79adec5c 100644 --- a/common/rfb/CConnection.cxx +++ b/common/rfb/CConnection.cxx @@ -52,7 +52,7 @@ CConnection::CConnection() supportsDesktopResize(false), supportsLEDState(false), is(0), os(0), reader_(0), writer_(0), shared(false), - state_(RFBSTATE_UNINITIALISED), serverName(strDup("")), + state_(RFBSTATE_UNINITIALISED), pendingPFChange(false), preferredEncoding(encodingTight), compressLevel(2), qualityLevel(-1), formatChange(false), encodingChange(false), @@ -72,7 +72,7 @@ void CConnection::setServerName(const char* name_) { if (name_ == NULL) name_ = ""; - serverName.replaceBuf(strDup(name_)); + serverName = name_; } void CConnection::setStreams(rdr::InStream* is_, rdr::OutStream* os_) diff --git a/common/rfb/CConnection.h b/common/rfb/CConnection.h index 7e5c611e..0cf47962 100644 --- a/common/rfb/CConnection.h +++ b/common/rfb/CConnection.h @@ -27,7 +27,6 @@ #include #include #include -#include namespace rfb { @@ -206,7 +205,7 @@ namespace rfb { // Access method used by SSecurity implementations that can verify servers' // Identities, to determine the unique(ish) name of the server. - const char* getServerName() const { return serverName.buf; } + const char* getServerName() const { return serverName.c_str(); } bool isSecure() const { return csecurity ? csecurity->isSecure() : false; } @@ -271,7 +270,7 @@ namespace rfb { bool shared; stateEnum state_; - CharArray serverName; + std::string serverName; bool pendingPFChange; rfb::PixelFormat pendingPF; diff --git a/common/rfb/CMakeLists.txt b/common/rfb/CMakeLists.txt index e18cff34..85cdc2db 100644 --- a/common/rfb/CMakeLists.txt +++ b/common/rfb/CMakeLists.txt @@ -32,7 +32,6 @@ add_library(rfb STATIC Logger.cxx Logger_file.cxx Logger_stdio.cxx - Password.cxx PixelBuffer.cxx PixelFormat.cxx RREEncoder.cxx @@ -64,6 +63,7 @@ add_library(rfb STATIC ZRLEEncoder.cxx ZRLEDecoder.cxx encodings.cxx + obfuscate.cxx util.cxx) target_link_libraries(rfb os rdr) diff --git a/common/rfb/CSecurityRSAAES.cxx b/common/rfb/CSecurityRSAAES.cxx index f48e2523..24d1a9fe 100644 --- a/common/rfb/CSecurityRSAAES.cxx +++ b/common/rfb/CSecurityRSAAES.cxx @@ -208,13 +208,12 @@ void CSecurityRSAAES::verifyServer() sha1_update(&ctx, serverKey.size, serverKeyE); sha1_digest(&ctx, sizeof(f), f); const char *title = "Server key fingerprint"; - CharArray text; - text.format( + std::string text = strFormat( "The server has provided the following identifying information:\n" "Fingerprint: %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n" "Please verify that the information is correct and press \"Yes\". " "Otherwise press \"No\"", f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7]); - if (!msg->showMsgBox(UserMsgBox::M_YESNO, title, text.buf)) + if (!msg->showMsgBox(UserMsgBox::M_YESNO, title, text.c_str())) throw AuthFailureException("server key mismatch"); } diff --git a/common/rfb/CSecurityTLS.cxx b/common/rfb/CSecurityTLS.cxx index c702280d..92a89193 100644 --- a/common/rfb/CSecurityTLS.cxx +++ b/common/rfb/CSecurityTLS.cxx @@ -354,12 +354,14 @@ void CSecurityTLS::checkSession() throw AuthFailureException("decoding of certificate failed"); if (gnutls_x509_crt_check_hostname(crt, client->getServerName()) == 0) { - CharArray text; + std::string text; vlog.debug("hostname mismatch"); - text.format("Hostname (%s) does not match the server certificate, " - "do you want to continue?", client->getServerName()); + text = strFormat("Hostname (%s) does not match the server " + "certificate, do you want to continue?", + client->getServerName()); if (!msg->showMsgBox(UserMsgBox::M_YESNO, - "Certificate hostname mismatch", text.buf)) + "Certificate hostname mismatch", + text.c_str())) throw AuthFailureException("Certificate hostname mismatch"); } @@ -395,10 +397,10 @@ void CSecurityTLS::checkSession() "path for known hosts storage"); } - CharArray dbPath(strlen(homeDir) + strlen("/x509_known_hosts") + 1); - sprintf(dbPath.buf, "%s/x509_known_hosts", homeDir); + std::string dbPath; + dbPath = (std::string)homeDir + "/x509_known_hosts"; - err = gnutls_verify_stored_pubkey(dbPath.buf, NULL, + err = gnutls_verify_stored_pubkey(dbPath.c_str(), NULL, client->getServerName(), NULL, GNUTLS_CRT_X509, &cert_list[0], 0); @@ -425,73 +427,94 @@ void CSecurityTLS::checkSession() /* New host */ if (err == GNUTLS_E_NO_CERTIFICATE_FOUND) { - CharArray text; + std::string text; vlog.debug("Server host not previously known"); vlog.debug("%s", info.data); if (status & (GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_SIGNER_NOT_CA)) { - text.format("This certificate has been signed by an unknown " - "authority:\n\n%s\n\nSomeone could be trying to " - "impersonate the site and you should not " - "continue.\n\nDo you want to make an exception " - "for this server?", info.data); + text = strFormat("This certificate has been signed by an " + "unknown authority:\n" + "\n" + "%s\n" + "\n" + "Someone could be trying to impersonate the " + "site and you should not continue.\n" + "\n" + "Do you want to make an exception for this " + "server?", info.data); if (!msg->showMsgBox(UserMsgBox::M_YESNO, "Unknown certificate issuer", - text.buf)) + text.c_str())) throw AuthFailureException("Unknown certificate issuer"); } if (status & GNUTLS_CERT_EXPIRED) { - text.format("This certificate has expired:\n\n%s\n\nSomeone " - "could be trying to impersonate the site and you " - "should not continue.\n\nDo you want to make an " - "exception for this server?", info.data); + text = strFormat("This certificate has expired:\n" + "\n" + "%s\n" + "\n" + "Someone could be trying to impersonate the " + "site and you should not continue.\n" + "\n" + "Do you want to make an exception for this " + "server?", info.data); if (!msg->showMsgBox(UserMsgBox::M_YESNO, "Expired certificate", - text.buf)) + text.c_str())) throw AuthFailureException("Expired certificate"); } } else if (err == GNUTLS_E_CERTIFICATE_KEY_MISMATCH) { - CharArray text; + std::string text; vlog.debug("Server host key mismatch"); vlog.debug("%s", info.data); if (status & (GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_SIGNER_NOT_CA)) { - text.format("This host is previously known with a different " - "certificate, and the new certificate has been " - "signed by an unknown authority:\n\n%s\n\nSomeone " - "could be trying to impersonate the site and you " - "should not continue.\n\nDo you want to make an " - "exception for this server?", info.data); + text = strFormat("This host is previously known with a " + "different certificate, and the new " + "certificate has been signed by an " + "unknown authority:\n" + "\n" + "%s\n" + "\n" + "Someone could be trying to impersonate the " + "site and you should not continue.\n" + "\n" + "Do you want to make an exception for this " + "server?", info.data); if (!msg->showMsgBox(UserMsgBox::M_YESNO, "Unexpected server certificate", - text.buf)) + text.c_str())) throw AuthFailureException("Unexpected server certificate"); } if (status & GNUTLS_CERT_EXPIRED) { - text.format("This host is previously known with a different " - "certificate, and the new certificate has expired:" - "\n\n%s\n\nSomeone could be trying to impersonate " - "the site and you should not continue.\n\nDo you " - "want to make an exception for this server?", - info.data); + text = strFormat("This host is previously known with a " + "different certificate, and the new " + "certificate has expired:\n" + "\n" + "%s\n" + "\n" + "Someone could be trying to impersonate the " + "site and you should not continue.\n" + "\n" + "Do you want to make an exception for this " + "server?", info.data); if (!msg->showMsgBox(UserMsgBox::M_YESNO, "Unexpected server certificate", - text.buf)) + text.c_str())) throw AuthFailureException("Unexpected server certificate"); } } - if (gnutls_store_pubkey(dbPath.buf, NULL, client->getServerName(), + if (gnutls_store_pubkey(dbPath.c_str(), NULL, client->getServerName(), NULL, GNUTLS_CRT_X509, &cert_list[0], 0, 0)) vlog.error("Failed to store server certificate to known hosts database"); diff --git a/common/rfb/Configuration.cxx b/common/rfb/Configuration.cxx index 9cbfa53d..0fc2bde6 100644 --- a/common/rfb/Configuration.cxx +++ b/common/rfb/Configuration.cxx @@ -133,7 +133,7 @@ VoidParameter* Configuration::get(const char* param) void Configuration::list(int width, int nameWidth) { VoidParameter* current = head; - fprintf(stderr, "%s Parameters:\n", name.buf); + fprintf(stderr, "%s Parameters:\n", name.c_str()); while (current) { std::string def_str = current->getDefaultStr(); const char* desc = current->getDescription(); diff --git a/common/rfb/Configuration.h b/common/rfb/Configuration.h index 20552364..eef89d93 100644 --- a/common/rfb/Configuration.h +++ b/common/rfb/Configuration.h @@ -44,9 +44,11 @@ #ifndef __RFB_CONFIGURATION_H__ #define __RFB_CONFIGURATION_H__ -#include +#include +#include -#include +#include +#include namespace os { class Mutex; } @@ -62,10 +64,10 @@ namespace rfb { class Configuration { public: // - Create a new Configuration object - Configuration(const char* name_) : name(strDup(name_)), head(0), _next(0) {} + Configuration(const char* name_) : name(name_), head(0), _next(0) {} // - Return the buffer containing the Configuration's name - const char* getName() const { return name.buf; } + const char* getName() const { return name.c_str(); } // - Set named parameter to value bool set(const char* param, const char* value, bool immutable=false); @@ -131,7 +133,7 @@ namespace rfb { friend struct ParameterIterator; // Name for this Configuration - CharArray name; + std::string name; // - Pointer to first Parameter in this group VoidParameter* head; diff --git a/common/rfb/Congestion.cxx b/common/rfb/Congestion.cxx index f642752e..1e252165 100644 --- a/common/rfb/Congestion.cxx +++ b/common/rfb/Congestion.cxx @@ -38,6 +38,7 @@ #endif #include +#include #include #ifdef __linux__ diff --git a/common/rfb/KeyRemapper.cxx b/common/rfb/KeyRemapper.cxx index 700ae298..731eb256 100644 --- a/common/rfb/KeyRemapper.cxx +++ b/common/rfb/KeyRemapper.cxx @@ -21,6 +21,7 @@ #endif #include +#include #include diff --git a/common/rfb/SConnection.cxx b/common/rfb/SConnection.cxx index 211fbd98..244fb324 100644 --- a/common/rfb/SConnection.cxx +++ b/common/rfb/SConnection.cxx @@ -247,7 +247,7 @@ bool SConnection::processSecurityMsg() state_ = RFBSTATE_SECURITY_FAILURE; // Introduce a slight delay of the authentication failure response // to make it difficult to brute force a password - authFailureMsg.replaceBuf(strDup(e.str())); + authFailureMsg = e.str(); authFailureTimer.start(100); return true; } @@ -296,9 +296,8 @@ bool SConnection::handleAuthFailureTimeout(Timer* /*t*/) try { os->writeU32(secResultFailed); if (!client.beforeVersion(3,8)) { // 3.8 onwards have failure message - const char* reason = authFailureMsg.buf; - os->writeU32(strlen(reason)); - os->writeBytes(reason, strlen(reason)); + os->writeU32(authFailureMsg.size()); + os->writeBytes(authFailureMsg.data(), authFailureMsg.size()); } os->flush(); } catch (rdr::Exception& e) { @@ -306,7 +305,7 @@ bool SConnection::handleAuthFailureTimeout(Timer* /*t*/) return false; } - close(authFailureMsg.buf); + close(authFailureMsg.c_str()); return false; } diff --git a/common/rfb/SConnection.h b/common/rfb/SConnection.h index 113811b9..54acdd9c 100644 --- a/common/rfb/SConnection.h +++ b/common/rfb/SConnection.h @@ -257,7 +257,7 @@ namespace rfb { SSecurity* ssecurity; MethodTimer authFailureTimer; - CharArray authFailureMsg; + std::string authFailureMsg; stateEnum state_; int32_t preferredEncoding; diff --git a/common/rfb/SSecurityRSAAES.cxx b/common/rfb/SSecurityRSAAES.cxx index 4cca7d6d..042e4838 100644 --- a/common/rfb/SSecurityRSAAES.cxx +++ b/common/rfb/SSecurityRSAAES.cxx @@ -571,18 +571,18 @@ void SSecurityRSAAES::verifyUserPass() void SSecurityRSAAES::verifyPass() { VncAuthPasswdGetter* pg = &SSecurityVncAuth::vncAuthPasswd; - PlainPasswd passwd, passwdReadOnly; + std::string passwd, passwdReadOnly; pg->getVncAuthPasswd(&passwd, &passwdReadOnly); - if (!passwd.buf) + if (passwd.empty()) throw AuthFailureException("No password configured for VNC Auth"); - if (strcmp(password, passwd.buf) == 0) { + if (password == passwd) { accessRights = SConnection::AccessDefault; return; } - if (passwdReadOnly.buf && strcmp(password, passwdReadOnly.buf) == 0) { + if (!passwdReadOnly.empty() && password == passwdReadOnly) { accessRights = SConnection::AccessView; return; } diff --git a/common/rfb/SSecurityVncAuth.cxx b/common/rfb/SSecurityVncAuth.cxx index bb644cf2..cbd0ccd2 100644 --- a/common/rfb/SSecurityVncAuth.cxx +++ b/common/rfb/SSecurityVncAuth.cxx @@ -28,10 +28,11 @@ #include #include #include -#include #include #include #include +#include +#include #include #include extern "C" { @@ -57,15 +58,15 @@ SSecurityVncAuth::SSecurityVncAuth(SConnection* sc) { } -bool SSecurityVncAuth::verifyResponse(const PlainPasswd &password) +bool SSecurityVncAuth::verifyResponse(const char* password) { uint8_t expectedResponse[vncAuthChallengeSize]; // Calculate the expected response uint8_t key[8]; - int pwdLen = strlen(password.buf); + int pwdLen = strlen(password); for (int i=0; i<8; i++) - key[i] = ireadBytes(response, vncAuthChallengeSize); - PlainPasswd passwd, passwdReadOnly; + std::string passwd, passwdReadOnly; pg->getVncAuthPasswd(&passwd, &passwdReadOnly); - if (!passwd.buf) + if (passwd.empty()) throw AuthFailureException("No password configured for VNC Auth"); - if (verifyResponse(passwd)) { + if (verifyResponse(passwd.c_str())) { accessRights = SConnection::AccessDefault; return true; } - if (passwdReadOnly.buf && verifyResponse(passwdReadOnly)) { + if (!passwdReadOnly.empty() && + verifyResponse(passwdReadOnly.c_str())) { accessRights = SConnection::AccessView; return true; } @@ -120,16 +122,11 @@ VncAuthPasswdParameter::VncAuthPasswdParameter(const char* name, : BinaryParameter(name, desc, 0, 0, ConfServer), passwdFile(passwdFile_) { } -void VncAuthPasswdParameter::getVncAuthPasswd(PlainPasswd *password, PlainPasswd *readOnlyPassword) { - ObfuscatedPasswd obfuscated, obfuscatedReadOnly; - std::vector data = getData(); - obfuscated.length = data.size(); - if (!data.empty()) { - obfuscated.buf = new char[data.size()]; - memcpy(obfuscated.buf, data.data(), data.size()); - } +void VncAuthPasswdParameter::getVncAuthPasswd(std::string *password, std::string *readOnlyPassword) { + std::vector obfuscated, obfuscatedReadOnly; + obfuscated = getData(); - if (obfuscated.length == 0) { + if (obfuscated.size() == 0) { if (passwdFile) { const char *fname = *passwdFile; if (!fname[0]) { @@ -144,21 +141,22 @@ void VncAuthPasswdParameter::getVncAuthPasswd(PlainPasswd *password, PlainPasswd } vlog.debug("reading password file"); - obfuscated.buf = new char[8]; - obfuscated.length = fread(obfuscated.buf, 1, 8, fp); - obfuscatedReadOnly.buf = new char[8]; - obfuscatedReadOnly.length = fread(obfuscatedReadOnly.buf, 1, 8, fp); + obfuscated.resize(8); + obfuscated.resize(fread(obfuscated.data(), 1, 8, fp)); + obfuscatedReadOnly.resize(8); + obfuscatedReadOnly.resize(fread(obfuscatedReadOnly.data(), 1, 8, fp)); fclose(fp); } else { vlog.info("%s parameter not set", getName()); } } + assert(password != NULL); + assert(readOnlyPassword != NULL); + try { - PlainPasswd plainPassword(obfuscated); - password->replaceBuf(plainPassword.takeBuf()); - PlainPasswd plainPasswordReadOnly(obfuscatedReadOnly); - readOnlyPassword->replaceBuf(plainPasswordReadOnly.takeBuf()); + *password = deobfuscate(obfuscated.data(), obfuscated.size()); + *readOnlyPassword = deobfuscate(obfuscatedReadOnly.data(), obfuscatedReadOnly.size()); } catch (...) { } } diff --git a/common/rfb/SSecurityVncAuth.h b/common/rfb/SSecurityVncAuth.h index c6c329c4..2bd27791 100644 --- a/common/rfb/SSecurityVncAuth.h +++ b/common/rfb/SSecurityVncAuth.h @@ -27,7 +27,6 @@ #include #include -#include #include #include @@ -37,7 +36,7 @@ namespace rfb { public: // getVncAuthPasswd() fills buffer of given password and readOnlyPassword. // If there was no read only password in the file, readOnlyPassword buffer is null. - virtual void getVncAuthPasswd(PlainPasswd *password, PlainPasswd *readOnlyPassword)=0; + virtual void getVncAuthPasswd(std::string *password, std::string *readOnlyPassword)=0; virtual ~VncAuthPasswdGetter() { } }; @@ -45,7 +44,7 @@ namespace rfb { class VncAuthPasswdParameter : public VncAuthPasswdGetter, BinaryParameter { public: VncAuthPasswdParameter(const char* name, const char* desc, StringParameter* passwdFile_); - virtual void getVncAuthPasswd(PlainPasswd *password, PlainPasswd *readOnlyPassword); + virtual void getVncAuthPasswd(std::string *password, std::string *readOnlyPassword); protected: StringParameter* passwdFile; }; @@ -60,7 +59,7 @@ namespace rfb { static StringParameter vncAuthPasswdFile; static VncAuthPasswdParameter vncAuthPasswd; private: - bool verifyResponse(const PlainPasswd &password); + bool verifyResponse(const char* password); enum {vncAuthChallengeSize = 16}; uint8_t challenge[vncAuthChallengeSize]; uint8_t response[vncAuthChallengeSize]; diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx index f27264c3..1d890c28 100644 --- a/common/rfb/VNCSConnectionST.cxx +++ b/common/rfb/VNCSConnectionST.cxx @@ -59,7 +59,7 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s, pointerEventTime(0), clientHasCursor(false) { setStreams(&sock->inStream(), &sock->outStream()); - peerEndpoint.buf = strDup(sock->getPeerEndpoint()); + peerEndpoint = sock->getPeerEndpoint(); // Kick off the idle timer if (rfb::Server::idleTimeout) { @@ -75,8 +75,9 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s, VNCSConnectionST::~VNCSConnectionST() { // If we reach here then VNCServerST is deleting us! - if (closeReason.buf) - vlog.info("closing %s: %s", peerEndpoint.buf, closeReason.buf); + if (!closeReason.empty()) + vlog.info("closing %s: %s", peerEndpoint.c_str(), + closeReason.c_str()); // Release any keys the client still had pressed while (!pressedKeys.empty()) { @@ -112,10 +113,10 @@ void VNCSConnectionST::close(const char* reason) SConnection::close(reason); // Log the reason for the close - if (!closeReason.buf) - closeReason.buf = strDup(reason); + if (closeReason.empty()) + closeReason = reason; else - vlog.debug("second close: %s (%s)", peerEndpoint.buf, reason); + vlog.debug("second close: %s (%s)", peerEndpoint.c_str(), reason); try { if (sock->outStream().hasBufferedData()) { diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h index 23215d24..79f0b4fe 100644 --- a/common/rfb/VNCSConnectionST.h +++ b/common/rfb/VNCSConnectionST.h @@ -112,7 +112,7 @@ namespace rfb { updates.add_copied(dest, delta); } - const char* getPeerEndpoint() const {return peerEndpoint.buf;} + const char* getPeerEndpoint() const {return peerEndpoint.c_str();} private: // SConnection callbacks @@ -166,7 +166,7 @@ namespace rfb { private: network::Socket* sock; - CharArray peerEndpoint; + std::string peerEndpoint; bool reverseConnection; bool inProcessMessages; @@ -197,7 +197,7 @@ namespace rfb { Point pointerEventPos; bool clientHasCursor; - CharArray closeReason; + std::string closeReason; }; } #endif diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx index aaa59eaa..1122b0a7 100644 --- a/common/rfb/VNCServerST.cxx +++ b/common/rfb/VNCServerST.cxx @@ -80,14 +80,14 @@ static LogWriter connectionsLog("Connections"); VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_) : blHosts(&blacklist), desktop(desktop_), desktopStarted(false), blockCounter(0), pb(0), ledState(ledUnknown), - name(strDup(name_)), pointerClient(0), clipboardClient(0), + name(name_), pointerClient(0), clipboardClient(0), comparer(0), cursor(new Cursor(0, 0, Point(), NULL)), renderedCursorInvalid(false), keyRemapper(&KeyRemapper::defInstance), idleTimer(this), disconnectTimer(this), connectTimer(this), frameTimer(this) { - slog.debug("creating single-threaded server %s", name.buf); + slog.debug("creating single-threaded server %s", name.c_str()); // FIXME: Do we really want to kick off these right away? if (rfb::Server::maxIdleTime) @@ -98,7 +98,7 @@ VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_) VNCServerST::~VNCServerST() { - slog.debug("shutting down server %s", name.buf); + slog.debug("shutting down server %s", name.c_str()); // Close any active clients, with appropriate logging & cleanup closeClients("Server shutdown"); @@ -175,14 +175,14 @@ void VNCServerST::removeSocket(network::Socket* sock) { handleClipboardAnnounce(*ci, false); clipboardRequestors.remove(*ci); - CharArray name(strDup((*ci)->getPeerEndpoint())); + std::string name((*ci)->getPeerEndpoint()); // - Delete the per-Socket resources delete *ci; clients.remove(*ci); - connectionsLog.status("closed: %s", name.buf); + connectionsLog.status("closed: %s", name.c_str()); // - Check that the desktop object is still required if (authClientCount() == 0) @@ -386,7 +386,7 @@ void VNCServerST::bell() void VNCServerST::setName(const char* name_) { - name.replaceBuf(strDup(name_)); + name = name_; std::list::iterator ci, ci_next; for (ci = clients.begin(); ci != clients.end(); ci = ci_next) { ci_next = ci; ci_next++; diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h index 26059574..028903c9 100644 --- a/common/rfb/VNCServerST.h +++ b/common/rfb/VNCServerST.h @@ -112,7 +112,7 @@ namespace rfb { const ScreenSet& getScreenLayout() const { return screenLayout; } const Cursor* getCursor() const { return cursor; } const Point& getCursorPos() const { return cursorPos; } - const char* getName() const { return name.buf; } + const char* getName() const { return name.c_str(); } unsigned getLEDState() const { return ledState; } // Event handlers @@ -183,7 +183,7 @@ namespace rfb { ScreenSet screenLayout; unsigned int ledState; - CharArray name; + std::string name; std::list clients; VNCSConnectionST* pointerClient; diff --git a/common/rfb/Password.cxx b/common/rfb/obfuscate.cxx similarity index 57% rename from common/rfb/Password.cxx rename to common/rfb/obfuscate.cxx index b1cce2bb..1f785893 100644 --- a/common/rfb/Password.cxx +++ b/common/rfb/obfuscate.cxx @@ -1,4 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. + * Copyright 2023 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,62 +25,45 @@ #include #endif +#include #include -#include + extern "C" { #include } #include -#include - -using namespace rfb; +#include static unsigned char d3desObfuscationKey[] = {23,82,107,6,35,78,88,7}; +std::vector rfb::obfuscate(const char *str) +{ + std::vector buf(8); -PlainPasswd::PlainPasswd() {} - -PlainPasswd::PlainPasswd(char* pwd) : CharArray(pwd) { -} - -PlainPasswd::PlainPasswd(size_t len) : CharArray(len) { -} - -PlainPasswd::PlainPasswd(const ObfuscatedPasswd& obfPwd) : CharArray(9) { - if (obfPwd.length < 8) - throw rdr::Exception("bad obfuscated password length"); - deskey(d3desObfuscationKey, DE1); - des((uint8_t*)obfPwd.buf, (uint8_t*)buf); - buf[8] = 0; -} + assert(str != NULL); -PlainPasswd::~PlainPasswd() { - replaceBuf(0); -} + size_t l = strlen(str), i; + for (i=0; i<8; i++) + buf[i] = i +#ifndef __RFB_OBFUSCATE_H__ +#define __RFB_OBFUSCATE_H__ -namespace rfb { +#include - class ObfuscatedPasswd; +#include +#include - class PlainPasswd : public CharArray { - public: - PlainPasswd(); - PlainPasswd(char* pwd); - PlainPasswd(size_t len); - PlainPasswd(const ObfuscatedPasswd& obfPwd); - ~PlainPasswd(); - void replaceBuf(char* b); - }; +namespace rfb { - class ObfuscatedPasswd : public CharArray { - public: - ObfuscatedPasswd(); - ObfuscatedPasswd(size_t l); - ObfuscatedPasswd(const PlainPasswd& plainPwd); - ~ObfuscatedPasswd(); - size_t length; - }; + std::vector obfuscate(const char *str); + std::string deobfuscate(const uint8_t *data, size_t len); } + #endif diff --git a/common/rfb/util.cxx b/common/rfb/util.cxx index 6f12ad7d..c5eeed92 100644 --- a/common/rfb/util.cxx +++ b/common/rfb/util.cxx @@ -1,5 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * Copyright 2011-2022 Pierre Ossman for Cendio AB + * Copyright 2011-2023 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -66,6 +66,33 @@ namespace rfb { delete [] s; } + std::string strFormat(const char *fmt, ...) + { + va_list ap; + int len; + char *buf; + std::string out; + + va_start(ap, fmt); + len = vsnprintf(NULL, 0, fmt, ap); + va_end(ap); + + if (len < 0) + return ""; + + buf = new char[len+1]; + + va_start(ap, fmt); + vsnprintf(buf, len+1, fmt, ap); + va_end(ap); + + out = buf; + + delete [] buf; + + return out; + } + std::vector strSplit(const char* src, const char delimiter) { diff --git a/common/rfb/util.h b/common/rfb/util.h index 2540ab3b..b361aa11 100644 --- a/common/rfb/util.h +++ b/common/rfb/util.h @@ -1,5 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * Copyright 2011-2022 Pierre Ossman for Cendio AB + * Copyright 2011-2023 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -61,6 +61,10 @@ namespace rfb { char* strDup(const char* s); void strFree(char* s); + // Formats according to printf(), with a dynamic allocation + std::string strFormat(const char *fmt, ...) + __attribute__((__format__ (__printf__, 1, 2))); + // Splits a string with the specified delimiter std::vector strSplit(const char* src, const char delimiter); diff --git a/unix/tx/TXButton.h b/unix/tx/TXButton.h index 35694333..a51f2ecd 100644 --- a/unix/tx/TXButton.h +++ b/unix/tx/TXButton.h @@ -59,8 +59,8 @@ public: // setText() changes the text in the button. void setText(const char* text_) { - text.buf = rfb::strDup(text_); - int textWidth = XTextWidth(defaultFS, text.buf, strlen(text.buf)); + text = text_; + int textWidth = XTextWidth(defaultFS, text.data(), text.size()); int textHeight = (defaultFS->ascent + defaultFS->descent); int newWidth = __rfbmax(width(), textWidth + xPad*2 + bevel*2); int newHeight = __rfbmax(height(), textHeight + yPad*2 + bevel*2); @@ -77,7 +77,7 @@ public: private: void paint() { - int tw = XTextWidth(defaultFS, text.buf, strlen(text.buf)); + int tw = XTextWidth(defaultFS, text.data(), text.size()); int startx = (width() - tw) / 2; int starty = (height() + defaultFS->ascent - defaultFS->descent) / 2; if (down || disabled_) { @@ -88,7 +88,7 @@ private: } XSetForeground(dpy, gc, disabled_ ? disabledFg : defaultFg); - XDrawString(dpy, win(), gc, startx, starty, text.buf, strlen(text.buf)); + XDrawString(dpy, win(), gc, startx, starty, text.data(), text.size()); } virtual void handleEvent(TXWindow* /*w*/, XEvent* ev) { @@ -115,7 +115,7 @@ private: } GC gc; - rfb::CharArray text; + std::string text; TXButtonCallback* cb; bool down; bool disabled_; diff --git a/unix/tx/TXLabel.h b/unix/tx/TXLabel.h index aba798cb..24b8cbb3 100644 --- a/unix/tx/TXLabel.h +++ b/unix/tx/TXLabel.h @@ -47,20 +47,20 @@ public: // setText() changes the text in the label. void setText(const char* text_) { - text.buf = rfb::strDup(text_); + text = text_; lines = 0; - int lineStart = 0; + size_t lineStart = 0; int textWidth = 0; - int i = -1; + size_t i = -1; do { i++; - if (text.buf[i] == '\n' || text.buf[i] == 0) { - int tw = XTextWidth(defaultFS, &text.buf[lineStart], i-lineStart); + if (i >= text.size() || text[i] == '\n') { + int tw = XTextWidth(defaultFS, &text[lineStart], i-lineStart); if (tw > textWidth) textWidth = tw; lineStart = i+1; lines++; } - } while (text.buf[i] != 0); + } while (i < text.size()); int textHeight = ((defaultFS->ascent + defaultFS->descent + lineSpacing) * lines); int newWidth = __rfbmax(width(), textWidth + xPad*2); @@ -93,19 +93,19 @@ private: } void paint() { - int lineNum = 0; - int lineStart = 0; - int i = -1; + size_t lineNum = 0; + size_t lineStart = 0; + size_t i = -1; do { i++; - if (text.buf[i] == '\n' || text.buf[i] == 0) { - int tw = XTextWidth(defaultFS, &text.buf[lineStart], i-lineStart); + if (i >= text.size() || text[i] == '\n') { + int tw = XTextWidth(defaultFS, &text[lineStart], i-lineStart); XDrawString(dpy, win(), defaultGC, xOffset(tw), yOffset(lineNum), - &text.buf[lineStart], i-lineStart); + &text[lineStart], i-lineStart); lineStart = i+1; lineNum++; } - } while (text.buf[i] != 0); + } while (i < text.size()); } virtual void handleEvent(TXWindow* /*w*/, XEvent* ev) { @@ -117,7 +117,7 @@ private: } int lineSpacing; - rfb::CharArray text; + std::string text; int lines; HAlign halign; VAlign valign; diff --git a/unix/vncpasswd/vncpasswd.cxx b/unix/vncpasswd/vncpasswd.cxx index 0ad3a52b..93ad6f6f 100644 --- a/unix/vncpasswd/vncpasswd.cxx +++ b/unix/vncpasswd/vncpasswd.cxx @@ -1,6 +1,7 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. * Copyright (C) 2010 Antoine Martin. All Rights Reserved. * Copyright (C) 2010 D. R. Commander. All Rights Reserved. + * Copyright 2018-2023 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,7 +31,8 @@ #include #include #include -#include + +#include #include @@ -58,16 +60,16 @@ static void enableEcho(bool enable) { tcsetattr(fileno(stdin), TCSAFLUSH, &attrs); } -static char* getpassword(const char* prompt) { - PlainPasswd buf(256); +static const char* getpassword(const char* prompt) { + static char buf[256]; if (prompt) fputs(prompt, stdout); enableEcho(false); - char* result = fgets(buf.buf, 256, stdin); + char* result = fgets(buf, 256, stdin); enableEcho(true); if (result) { if (result[strlen(result)-1] == '\n') result[strlen(result)-1] = 0; - return buf.takeBuf(); + return buf; } return 0; } @@ -78,12 +80,12 @@ static int encrypt_pipe() { // We support a maximum of two passwords right now for (i = 0;i < 2;i++) { - char *result = getpassword(NULL); + const char *result = getpassword(NULL); if (!result) break; - ObfuscatedPasswd obfuscated(result); - if (fwrite(obfuscated.buf, obfuscated.length, 1, stdout) != 1) { + std::vector obfuscated = obfuscate(result); + if (fwrite(obfuscated.data(), obfuscated.size(), 1, stdout) != 1) { fprintf(stderr,"Writing to stdout failed\n"); return 1; } @@ -96,15 +98,16 @@ static int encrypt_pipe() { return 0; } -static ObfuscatedPasswd* readpassword() { +static std::vector readpassword() { while (true) { - PlainPasswd passwd(getpassword("Password:")); - if (!passwd.buf) { + const char *passwd = getpassword("Password:"); + if (passwd == NULL) { perror("getpassword error"); exit(1); } - if (strlen(passwd.buf) < 6) { - if (strlen(passwd.buf) == 0) { + std::string first = passwd; + if (first.size() < 6) { + if (first.empty()) { fprintf(stderr,"Password not changed\n"); exit(1); } @@ -112,17 +115,18 @@ static ObfuscatedPasswd* readpassword() { continue; } - PlainPasswd passwd2(getpassword("Verify:")); - if (!passwd2.buf) { + passwd = getpassword("Verify:"); + if (passwd == NULL) { perror("getpass error"); exit(1); } - if (strcmp(passwd.buf, passwd2.buf) != 0) { + std::string second = passwd; + if (first != second) { fprintf(stderr,"Passwords don't match - try again\n"); continue; } - return new ObfuscatedPasswd(passwd); + return obfuscate(first.c_str()); } } @@ -162,8 +166,8 @@ int main(int argc, char** argv) } while (true) { - ObfuscatedPasswd* obfuscated = readpassword(); - ObfuscatedPasswd* obfuscatedReadOnly = 0; + std::vector obfuscated = readpassword(); + std::vector obfuscatedReadOnly; fprintf(stderr, "Would you like to enter a view-only password (y/n)? "); char yesno[3]; @@ -176,33 +180,24 @@ int main(int argc, char** argv) FILE* fp = fopen(fname,"w"); if (!fp) { fprintf(stderr,"Couldn't open %s for writing\n",fname); - delete obfuscated; - delete obfuscatedReadOnly; exit(1); } chmod(fname, S_IRUSR|S_IWUSR); - if (fwrite(obfuscated->buf, obfuscated->length, 1, fp) != 1) { + if (fwrite(obfuscated.data(), obfuscated.size(), 1, fp) != 1) { fprintf(stderr,"Writing to %s failed\n",fname); - delete obfuscated; - delete obfuscatedReadOnly; exit(1); } - delete obfuscated; - - if (obfuscatedReadOnly) { - if (fwrite(obfuscatedReadOnly->buf, obfuscatedReadOnly->length, 1, fp) != 1) { + if (!obfuscatedReadOnly.empty()) { + if (fwrite(obfuscatedReadOnly.data(), obfuscatedReadOnly.size(), 1, fp) != 1) { fprintf(stderr,"Writing to %s failed\n",fname); - delete obfuscatedReadOnly; exit(1); } } fclose(fp); - delete obfuscatedReadOnly; - return 0; } } diff --git a/unix/x0vncserver/Geometry.cxx b/unix/x0vncserver/Geometry.cxx index 37b4e74e..3f7f2863 100644 --- a/unix/x0vncserver/Geometry.cxx +++ b/unix/x0vncserver/Geometry.cxx @@ -24,6 +24,8 @@ #include #endif +#include + #include #include diff --git a/unix/x0vncserver/Image.cxx b/unix/x0vncserver/Image.cxx index b171c904..92d629f3 100644 --- a/unix/x0vncserver/Image.cxx +++ b/unix/x0vncserver/Image.cxx @@ -26,6 +26,7 @@ #include #include +#include #include #include diff --git a/unix/xserver/hw/vnc/RFBGlue.cc b/unix/xserver/hw/vnc/RFBGlue.cc index 4f63397e..6bf745fc 100644 --- a/unix/xserver/hw/vnc/RFBGlue.cc +++ b/unix/xserver/hw/vnc/RFBGlue.cc @@ -28,6 +28,7 @@ #include #include #include +#include #include "RFBGlue.h" diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc index 14b111ae..b5a58671 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.cc +++ b/unix/xserver/hw/vnc/XserverDesktop.cc @@ -172,10 +172,10 @@ void XserverDesktop::queryConnection(network::Socket* sock, return; } - queryConnectAddress.replaceBuf(strDup(sock->getPeerAddress())); + queryConnectAddress = sock->getPeerAddress(); if (!userName) userName = "(anonymous)"; - queryConnectUsername.replaceBuf(strDup(userName)); + queryConnectUsername = userName; queryConnectId = (uint32_t)(intptr_t)sock; queryConnectSocket = sock; @@ -428,8 +428,8 @@ void XserverDesktop::getQueryConnect(uint32_t* opaqueId, *username = ""; *timeout = 0; } else { - *address = queryConnectAddress.buf; - *username = queryConnectUsername.buf; + *address = queryConnectAddress.c_str(); + *username = queryConnectUsername.c_str(); *timeout = queryConnectTimeout; } } diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h index 94f6f076..677097a6 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.h +++ b/unix/xserver/hw/vnc/XserverDesktop.h @@ -123,8 +123,8 @@ private: uint32_t queryConnectId; network::Socket* queryConnectSocket; - rfb::CharArray queryConnectAddress; - rfb::CharArray queryConnectUsername; + std::string queryConnectAddress; + std::string queryConnectUsername; rfb::Timer queryConnectTimer; OutputIdMap outputIdMap; diff --git a/vncviewer/ServerDialog.cxx b/vncviewer/ServerDialog.cxx index db39cd59..ec1e40e4 100644 --- a/vncviewer/ServerDialog.cxx +++ b/vncviewer/ServerDialog.cxx @@ -38,6 +38,7 @@ #include #include #include +#include #include "fltk/layout.h" #include "ServerDialog.h" diff --git a/vncviewer/UserDialog.cxx b/vncviewer/UserDialog.cxx index ff5b6123..7f8b3c8e 100644 --- a/vncviewer/UserDialog.cxx +++ b/vncviewer/UserDialog.cxx @@ -34,8 +34,8 @@ #include #include -#include #include +#include #include "fltk/layout.h" #include "fltk/util.h" @@ -91,18 +91,17 @@ void UserDialog::getUserPasswd(bool secure, std::string* user, } if (!user && passwordFileName[0]) { - ObfuscatedPasswd obfPwd(256); + std::vector obfPwd(256); FILE* fp; fp = fopen(passwordFileName, "rb"); if (!fp) throw rfb::Exception(_("Opening password file failed")); - obfPwd.length = fread(obfPwd.buf, 1, obfPwd.length, fp); + obfPwd.resize(fread(obfPwd.data(), 1, obfPwd.size(), fp)); fclose(fp); - PlainPasswd passwd(obfPwd); - *password = passwd.buf; + *password = deobfuscate(obfPwd.data(), obfPwd.size()); return; } diff --git a/win/rfb_win32/CurrentUser.cxx b/win/rfb_win32/CurrentUser.cxx index 153e415d..e4ef6ccf 100644 --- a/win/rfb_win32/CurrentUser.cxx +++ b/win/rfb_win32/CurrentUser.cxx @@ -110,10 +110,12 @@ ImpersonateCurrentUser::~ImpersonateCurrentUser() { } -UserName::UserName() : CharArray(UNLEN+1) { +UserName::UserName() { + char buf[UNLEN+1]; DWORD len = UNLEN+1; if (!GetUserName(buf, &len)) throw rdr::SystemException("GetUserName failed", GetLastError()); + assign(buf); } diff --git a/win/rfb_win32/CurrentUser.h b/win/rfb_win32/CurrentUser.h index 37fa65b2..12c4b49f 100644 --- a/win/rfb_win32/CurrentUser.h +++ b/win/rfb_win32/CurrentUser.h @@ -26,7 +26,8 @@ #ifndef __RFB_WIN32_CURRENT_USER_H__ #define __RFB_WIN32_CURRENT_USER_H__ -#include +#include + #include #include @@ -67,7 +68,7 @@ namespace rfb { // Returns the name of the user the thread is currently running as. // Raises a SystemException in case of error. - struct UserName : public CharArray { + struct UserName : public std::string { UserName(); }; diff --git a/win/rfb_win32/Dialog.cxx b/win/rfb_win32/Dialog.cxx index 6fee7fd7..8e2c1ee8 100644 --- a/win/rfb_win32/Dialog.cxx +++ b/win/rfb_win32/Dialog.cxx @@ -207,7 +207,7 @@ BOOL PropSheetPage::dialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam PropSheet::PropSheet(HINSTANCE inst_, const char* title_, std::list pages_, HICON icon_) -: icon(icon_), pages(pages_), inst(inst_), title(strDup(title_)), handle(0), alreadyShowing(0) { +: icon(icon_), pages(pages_), inst(inst_), title(title_), handle(0), alreadyShowing(0) { } PropSheet::~PropSheet() { @@ -264,7 +264,7 @@ bool PropSheet::showPropSheet(HWND owner, bool showApply, bool showCtxtHelp, boo header.pfnCallback = removeCtxtHelp; header.hwndParent = owner; header.hInstance = inst; - header.pszCaption = title.buf; + header.pszCaption = title.c_str(); header.nPages = count; header.nStartPage = 0; header.phpage = hpages; @@ -282,7 +282,7 @@ bool PropSheet::showPropSheet(HWND owner, bool showApply, bool showCtxtHelp, boo (void)capture; #ifdef _DIALOG_CAPTURE if (capture) { - plog.info("capturing \"%s\"", title.buf); + plog.info("capturing \"%s\"", title.c_str()); char* tmpdir = getenv("TEMP"); HDC dc = GetWindowDC(handle); DeviceFrameBuffer fb(dc); diff --git a/win/rfb_win32/Dialog.h b/win/rfb_win32/Dialog.h index f2d718ce..d1a8e831 100644 --- a/win/rfb_win32/Dialog.h +++ b/win/rfb_win32/Dialog.h @@ -25,12 +25,12 @@ #ifndef __RFB_WIN32_DIALOG_H__ #define __RFB_WIN32_DIALOG_H__ +#include + #include #include #include -#include - namespace rfb { namespace win32 { @@ -131,7 +131,7 @@ namespace rfb { HICON icon; std::list pages; HINSTANCE inst; - CharArray title; + std::string title; HWND handle; bool alreadyShowing; }; diff --git a/win/rfb_win32/LaunchProcess.cxx b/win/rfb_win32/LaunchProcess.cxx index 7d17caf7..5e702a00 100644 --- a/win/rfb_win32/LaunchProcess.cxx +++ b/win/rfb_win32/LaunchProcess.cxx @@ -33,7 +33,7 @@ using namespace win32; LaunchProcess::LaunchProcess(const char* exeName_, const char* params_) -: exeName(strDup(exeName_)), params(strDup(params_)) { +: exeName(exeName_), params(params_) { memset(&procInfo, 0, sizeof(procInfo)); } @@ -64,30 +64,32 @@ void LaunchProcess::start(HANDLE userToken, bool createConsole) { sinfo.lpDesktop = desktopName; // - Concoct a suitable command-line - CharArray exePath; - if (!strContains(exeName.buf, '\\')) { + std::string exePath; + if (exeName.find('\\') == std::string::npos) { ModuleFileName filename; - CharArray path(strDup(filename.buf)); - if (strContains(path.buf, '\\')) - *strrchr(path.buf, '\\') = '\0'; - exePath.buf = new char[strlen(path.buf) + strlen(exeName.buf) + 2]; - sprintf(exePath.buf, "%s\\%s", path.buf, exeName.buf); + std::string path(filename.buf); + if (path.rfind('\\') != std::string::npos) + path.resize(path.rfind('\\')); + exePath = path + '\\' + exeName; } else { - exePath.buf = strDup(exeName.buf); + exePath = exeName; } // - Start the process // Note: We specify the exe's precise path in the ApplicationName parameter, // AND include the name as the first part of the CommandLine parameter, // because CreateProcess doesn't make ApplicationName argv[0] in C programs. - CharArray cmdLine(strlen(exeName.buf) + 3 + strlen(params.buf) + 1); - sprintf(cmdLine.buf, "\"%s\" %s", exeName.buf, params.buf); + std::string cmdLine; + cmdLine = (std::string)"\"" + exeName + "\" " + params; DWORD flags = createConsole ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW; BOOL success; if (userToken != INVALID_HANDLE_VALUE) - success = CreateProcessAsUser(userToken, exePath.buf, cmdLine.buf, 0, 0, FALSE, flags, 0, 0, &sinfo, &procInfo); + success = CreateProcessAsUser(userToken, exePath.c_str(), + (char*)cmdLine.c_str(), 0, 0, FALSE, + flags, 0, 0, &sinfo, &procInfo); else - success = CreateProcess(exePath.buf, cmdLine.buf, 0, 0, FALSE, flags, 0, 0, &sinfo, &procInfo); + success = CreateProcess(exePath.c_str(), (char*)cmdLine.c_str(), 0, + 0, FALSE, flags, 0, 0, &sinfo, &procInfo); if (!success) throw rdr::SystemException("unable to launch process", GetLastError()); diff --git a/win/rfb_win32/LaunchProcess.h b/win/rfb_win32/LaunchProcess.h index dc74682a..4cc8a92c 100644 --- a/win/rfb_win32/LaunchProcess.h +++ b/win/rfb_win32/LaunchProcess.h @@ -24,9 +24,9 @@ #ifndef __RFB_WIN32_LAUNCHPROCESS_H__ #define __RFB_WIN32_LAUNCHPROCESS_H__ -#include +#include -#include +#include namespace rfb { @@ -60,8 +60,8 @@ namespace rfb { PROCESS_INFORMATION procInfo; DWORD returnCode; protected: - CharArray exeName; - CharArray params; + std::string exeName; + std::string params; }; diff --git a/win/rfb_win32/MsgBox.h b/win/rfb_win32/MsgBox.h index 30492974..25d36383 100644 --- a/win/rfb_win32/MsgBox.h +++ b/win/rfb_win32/MsgBox.h @@ -19,9 +19,9 @@ #ifndef __RFB_WIN32_MSGBOX_H__ #define __RFB_WIN32_MSGBOX_H__ -#include +#include -#include +#include namespace rfb { namespace win32 { @@ -49,13 +49,12 @@ namespace rfb { flags |= MB_TOPMOST | MB_SETFOREGROUND; int len = strlen(AppName) + 1; if (msgType) len += strlen(msgType) + 3; - CharArray title(new char[len]); - strcpy(title.buf, AppName); + std::string title = AppName; if (msgType) { - strcat(title.buf, " : "); - strcat(title.buf, msgType); + title += " : "; + title += msgType; } - return MessageBox(parent, msg, title.buf, flags); + return MessageBox(parent, msg, title.c_str(), flags); } }; diff --git a/win/rfb_win32/MsgWindow.cxx b/win/rfb_win32/MsgWindow.cxx index 1a987475..251b2762 100644 --- a/win/rfb_win32/MsgWindow.cxx +++ b/win/rfb_win32/MsgWindow.cxx @@ -98,21 +98,21 @@ static MsgWindowClass baseClass; // -=- MsgWindow // -MsgWindow::MsgWindow(const char* name_) : name(strDup(name_)), handle(0) { - vlog.debug("creating window \"%s\"", name.buf); +MsgWindow::MsgWindow(const char* name_) : name(name_), handle(0) { + vlog.debug("creating window \"%s\"", name.c_str()); handle = CreateWindow((const char*)(intptr_t)baseClass.classAtom, - name.buf, WS_OVERLAPPED, 0, 0, 10, 10, 0, 0, + name.c_str(), WS_OVERLAPPED, 0, 0, 10, 10, 0, 0, baseClass.instance, this); if (!handle) { throw rdr::SystemException("unable to create WMNotifier window instance", GetLastError()); } - vlog.debug("created window \"%s\" (%p)", name.buf, handle); + vlog.debug("created window \"%s\" (%p)", name.c_str(), handle); } MsgWindow::~MsgWindow() { if (handle) DestroyWindow(handle); - vlog.debug("destroyed window \"%s\" (%p)", name.buf, handle); + vlog.debug("destroyed window \"%s\" (%p)", name.c_str(), handle); } LRESULT diff --git a/win/rfb_win32/MsgWindow.h b/win/rfb_win32/MsgWindow.h index 22ff1b85..5ede8280 100644 --- a/win/rfb_win32/MsgWindow.h +++ b/win/rfb_win32/MsgWindow.h @@ -24,9 +24,9 @@ #ifndef __RFB_WIN32_MSG_WINDOW_H__ #define __RFB_WIN32_MSG_WINDOW_H__ -#include +#include -#include +#include namespace rfb { @@ -37,13 +37,13 @@ namespace rfb { MsgWindow(const char* _name); virtual ~MsgWindow(); - const char* getName() {return name.buf;} + const char* getName() {return name.c_str();} HWND getHandle() const {return handle;} virtual LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam); protected: - CharArray name; + std::string name; HWND handle; }; diff --git a/win/rfb_win32/Registry.cxx b/win/rfb_win32/Registry.cxx index b1e8b07d..d0db60e2 100644 --- a/win/rfb_win32/Registry.cxx +++ b/win/rfb_win32/Registry.cxx @@ -29,6 +29,7 @@ #include #include #include +#include // These flags are required to control access control inheritance, // but are not defined by VC6's headers. These definitions comes diff --git a/win/rfb_win32/Service.cxx b/win/rfb_win32/Service.cxx index fe85e6c6..259eb762 100644 --- a/win/rfb_win32/Service.cxx +++ b/win/rfb_win32/Service.cxx @@ -30,6 +30,7 @@ #include #include #include +#include using namespace rdr; @@ -321,12 +322,12 @@ bool rfb::win32::registerService(const char* name, } // - Add the supplied extra parameters to the command line - CharArray cmdline(cmdline_len+strlen(defaultcmdline)); - sprintf(cmdline.buf, "\"%s\" %s", buffer.buf, defaultcmdline); + std::string cmdline; + cmdline = strFormat("\"%s\" %s", buffer.buf, defaultcmdline); for (i=0; i #include #include +#include #include using namespace rfb; diff --git a/win/rfb_win32/Win32Util.cxx b/win/rfb_win32/Win32Util.cxx index e806b1db..002bf2bd 100644 --- a/win/rfb_win32/Win32Util.cxx +++ b/win/rfb_win32/Win32Util.cxx @@ -73,14 +73,14 @@ const char* FileVersionInfo::getVerString(const char* name, DWORD langId) { } std::string langIdStr(binToHex(langIdBuf, sizeof(langId))); - CharArray infoName(strlen("StringFileInfo") + 4 + strlen(name) + strlen(langIdStr.c_str())); - sprintf(infoName.buf, "\\StringFileInfo\\%s\\%s", langIdStr.c_str(), name); + std::string infoName; + infoName = strFormat("\\StringFileInfo\\%s\\%s", langIdStr.c_str(), name); // Locate the required version string within the version info char* buffer = 0; UINT length = 0; - if (!VerQueryValue(buf, infoName.buf, (void**)&buffer, &length)) { - printf("unable to find %s version string", infoName.buf); + if (!VerQueryValue(buf, infoName.c_str(), (void**)&buffer, &length)) { + printf("unable to find %s version string", infoName.c_str()); throw rdr::Exception("VerQueryValue failed"); } return buffer; diff --git a/win/vncconfig/Authentication.h b/win/vncconfig/Authentication.h index cc162077..a69f7592 100644 --- a/win/vncconfig/Authentication.h +++ b/win/vncconfig/Authentication.h @@ -32,7 +32,6 @@ #ifdef HAVE_GNUTLS #include #endif -#include static rfb::BoolParameter queryOnlyIfLoggedOn("QueryOnlyIfLoggedOn", "Only prompt for a local user to accept incoming connections if there is a user logged on", false); @@ -113,9 +112,9 @@ namespace rfb { static bool haveVncPassword() { - PlainPasswd password, passwordReadOnly; + std::string password, passwordReadOnly; SSecurityVncAuth::vncAuthPasswd.getVncAuthPasswd(&password, &passwordReadOnly); - return password.buf && strlen(password.buf) != 0; + return !password.empty(); } static void verifyVncPassword(const RegKey& regKey) { diff --git a/win/vncconfig/Connections.h b/win/vncconfig/Connections.h index 1f974454..1cf01777 100644 --- a/win/vncconfig/Connections.h +++ b/win/vncconfig/Connections.h @@ -42,47 +42,45 @@ namespace rfb { public: ConnHostDialog() : Dialog(GetModuleHandle(0)) {} bool showDialog(const char* pat) { - pattern.replaceBuf(strDup(pat)); + pattern = pat; return Dialog::showDialog(MAKEINTRESOURCE(IDD_CONN_HOST)); } void initDialog() { - if (strlen(pattern.buf) == 0) - pattern.replaceBuf(strDup("+")); + if (pattern.empty()) + pattern = "+"; - if (pattern.buf[0] == '+') + if (pattern[0] == '+') setItemChecked(IDC_ALLOW, true); - else if (pattern.buf[0] == '?') + else if (pattern[0] == '?') setItemChecked(IDC_QUERY, true); else setItemChecked(IDC_DENY, true); - setItemString(IDC_HOST_PATTERN, &pattern.buf[1]); - pattern.replaceBuf(0); + setItemString(IDC_HOST_PATTERN, &pattern.c_str()[1]); + pattern.clear(); } bool onOk() { - CharArray host(strDup(getItemString(IDC_HOST_PATTERN))); - CharArray newPat(strlen(host.buf)+2); + std::string newPat; if (isItemChecked(IDC_ALLOW)) - newPat.buf[0] = '+'; + newPat = '+'; else if (isItemChecked(IDC_QUERY)) - newPat.buf[0] = '?'; + newPat = '?'; else - newPat.buf[0] = '-'; - newPat.buf[1] = 0; - strcat(newPat.buf, host.buf); + newPat = '-'; + newPat += getItemString(IDC_HOST_PATTERN); try { - network::TcpFilter::Pattern pat(network::TcpFilter::parsePattern(newPat.buf)); - pattern.replaceBuf(strDup(network::TcpFilter::patternToStr(pat).c_str())); + network::TcpFilter::Pattern pat(network::TcpFilter::parsePattern(newPat.c_str())); + pattern = network::TcpFilter::patternToStr(pat); } catch(rdr::Exception& e) { MsgBox(NULL, e.str(), MB_ICONEXCLAMATION | MB_OK); return false; } return true; } - const char* getPattern() {return pattern.buf;} + const char* getPattern() {return pattern.c_str();} protected: - CharArray pattern; + std::string pattern; }; class ConnectionsPage : public PropSheetPage { diff --git a/win/vncconfig/Legacy.cxx b/win/vncconfig/Legacy.cxx index bbd796d0..b21bccd7 100644 --- a/win/vncconfig/Legacy.cxx +++ b/win/vncconfig/Legacy.cxx @@ -38,10 +38,9 @@ void LegacyPage::LoadPrefs() // settings from HKCU/Software/ORL/WinVNC3. // Get the name of the current user - CharArray username; + std::string username; try { - UserName name; - username.buf = name.takeBuf(); + username = UserName(); } catch (rdr::SystemException& e) { if (e.err != ERROR_NOT_LOGGED_ON) throw; @@ -64,8 +63,7 @@ void LegacyPage::LoadPrefs() std::string authHosts = winvnc3.getString("AuthHosts", ""); if (!authHosts.empty()) { - CharArray newHosts; - newHosts.buf = strDup(""); + std::string newHosts; // Reformat AuthHosts to Hosts. Wish I'd left the format the same. :( :( :( try { @@ -107,20 +105,14 @@ void LegacyPage::LoadPrefs() strcat(pattern, buf); // Append this pattern to the Hosts value - int length = strlen(newHosts.buf) + strlen(pattern) + 2; - CharArray tmpHosts(length); - strcpy(tmpHosts.buf, pattern); - if (strlen(newHosts.buf)) { - strcat(tmpHosts.buf, ","); - strcat(tmpHosts.buf, newHosts.buf); - } - delete [] newHosts.buf; - newHosts.buf = tmpHosts.takeBuf(); + if (!newHosts.empty()) + newHosts += ","; + newHosts += pattern; } } // Finally, save the Hosts value - regKey.setString("Hosts", newHosts.buf); + regKey.setString("Hosts", newHosts.c_str()); } catch (rdr::Exception&) { MsgBox(0, "Unable to convert AuthHosts setting to Hosts format.", MB_ICONWARNING | MB_OK); @@ -157,10 +149,10 @@ void LegacyPage::LoadPrefs() } // Open the local, user-specific settings - if (userSettings && username.buf) { + if (userSettings && !username.empty()) { try { RegKey userKey; - userKey.openKey(winvnc3, username.buf); + userKey.openKey(winvnc3, username.c_str()); vlog.info("loading local User prefs"); LoadUserPrefs(userKey); } catch(rdr::Exception& e) { diff --git a/win/vncconfig/PasswordDialog.cxx b/win/vncconfig/PasswordDialog.cxx index 0df97001..f35aeb54 100644 --- a/win/vncconfig/PasswordDialog.cxx +++ b/win/vncconfig/PasswordDialog.cxx @@ -19,7 +19,7 @@ #include #include #include -#include +#include using namespace rfb; using namespace win32; @@ -33,9 +33,9 @@ bool PasswordDialog::showDialog(HWND owner) { } bool PasswordDialog::onOk() { - PlainPasswd password1(strDup(getItemString(IDC_PASSWORD1))); - PlainPasswd password2(strDup(getItemString(IDC_PASSWORD2))); - if (strcmp(password1.buf, password2.buf) != 0) { + std::string password1(getItemString(IDC_PASSWORD1)); + std::string password2(getItemString(IDC_PASSWORD2)); + if (password1 != password2) { MsgBox(0, "The supplied passwords do not match", MB_ICONEXCLAMATION | MB_OK); return false; @@ -45,8 +45,7 @@ bool PasswordDialog::onOk() { "Are you sure you wish to continue?", MB_YESNO | MB_ICONWARNING) == IDNO)) return false; - PlainPasswd password(strDup(password1.buf)); - ObfuscatedPasswd obfPwd(password); - regKey.setBinary("Password", obfPwd.buf, obfPwd.length); + std::vector obfPwd = obfuscate(password1.c_str()); + regKey.setBinary("Password", obfPwd.data(), obfPwd.size()); return true; } diff --git a/win/winvnc/AddNewClientDialog.h b/win/winvnc/AddNewClientDialog.h index 4bc489d8..44e15e70 100644 --- a/win/winvnc/AddNewClientDialog.h +++ b/win/winvnc/AddNewClientDialog.h @@ -34,20 +34,20 @@ namespace winvnc { virtual bool showDialog() { return Dialog::showDialog(MAKEINTRESOURCE(IDD_ADD_NEW_CLIENT)); } - const char* getHostName() const {return hostName.buf;} + const char* getHostName() const {return hostName.c_str();} protected: // Dialog methods (protected) virtual void initDialog() { - if (hostName.buf) - setItemString(IDC_HOST, hostName.buf); + if (!hostName.empty()) + setItemString(IDC_HOST, hostName.c_str()); } virtual bool onOk() { - hostName.replaceBuf(rfb::strDup(getItemString(IDC_HOST))); + hostName = getItemString(IDC_HOST); return true; } - rfb::CharArray hostName; + std::string hostName; }; }; diff --git a/win/winvnc/QueryConnectDialog.cxx b/win/winvnc/QueryConnectDialog.cxx index 76568c87..26bd9331 100644 --- a/win/winvnc/QueryConnectDialog.cxx +++ b/win/winvnc/QueryConnectDialog.cxx @@ -45,9 +45,8 @@ QueryConnectDialog::QueryConnectDialog(network::Socket* sock_, const char* userName_, VNCServerWin32* s) : Dialog(GetModuleHandle(0)), - sock(sock_), approve(false), server(s) { - peerIp.buf = strDup(sock->getPeerAddress()); - userName.buf = strDup(userName_); + sock(sock_), peerIp(sock->getPeerAddress()), userName(userName_), + approve(false), server(s) { } void QueryConnectDialog::startDialog() { @@ -76,10 +75,10 @@ void QueryConnectDialog::worker() { void QueryConnectDialog::initDialog() { if (!SetTimer(handle, 1, 1000, 0)) throw rdr::SystemException("SetTimer", GetLastError()); - setItemString(IDC_QUERY_HOST, peerIp.buf); - if (!userName.buf) - userName.buf = strDup("(anonymous)"); - setItemString(IDC_QUERY_USER, userName.buf); + setItemString(IDC_QUERY_HOST, peerIp.c_str()); + if (userName.empty()) + userName = "(anonymous)"; + setItemString(IDC_QUERY_USER, userName.c_str()); setCountdownLabel(); } diff --git a/win/winvnc/QueryConnectDialog.h b/win/winvnc/QueryConnectDialog.h index de5e31ee..36e885f9 100644 --- a/win/winvnc/QueryConnectDialog.h +++ b/win/winvnc/QueryConnectDialog.h @@ -22,7 +22,6 @@ #define __WINVNC_QUERY_CONNECT_DIALOG_H__ #include -#include namespace os { class Thread; } @@ -51,8 +50,8 @@ namespace winvnc { int countdown; network::Socket* sock; - rfb::CharArray peerIp; - rfb::CharArray userName; + std::string peerIp; + std::string userName; bool approve; VNCServerWin32* server; }; diff --git a/win/winvnc/STrayIcon.cxx b/win/winvnc/STrayIcon.cxx index 4ba147c2..e7032998 100644 --- a/win/winvnc/STrayIcon.cxx +++ b/win/winvnc/STrayIcon.cxx @@ -180,10 +180,8 @@ public: switch (command->dwData) { case 1: { - CharArray viewer(command->cbData + 1); - memcpy(viewer.buf, command->lpData, command->cbData); - viewer.buf[command->cbData] = 0; - return thread.server.addNewClient(viewer.buf) ? 1 : 0; + std::string viewer((char*)command->lpData, command->cbData); + return thread.server.addNewClient(viewer.c_str()) ? 1 : 0; } case 2: return thread.server.disconnectClients("IPC disconnect") ? 1 : 0; @@ -220,8 +218,8 @@ public: case WM_SET_TOOLTIP: { os::AutoMutex a(thread.lock); - if (thread.toolTip.buf) - setToolTip(thread.toolTip.buf); + if (!thread.toolTip.empty()) + setToolTip(thread.toolTip.c_str()); } return 0; @@ -280,8 +278,7 @@ void STrayIconThread::worker() { void STrayIconThread::setToolTip(const char* text) { if (!windowHandle) return; os::AutoMutex a(lock); - delete [] toolTip.buf; - toolTip.buf = strDup(text); + toolTip = text; PostMessage(windowHandle, WM_SET_TOOLTIP, 0, 0); } diff --git a/win/winvnc/STrayIcon.h b/win/winvnc/STrayIcon.h index c0385852..511c3ae2 100644 --- a/win/winvnc/STrayIcon.h +++ b/win/winvnc/STrayIcon.h @@ -47,7 +47,7 @@ namespace winvnc { os::Mutex* lock; DWORD thread_id; HWND windowHandle; - rfb::CharArray toolTip; + std::string toolTip; VNCServerWin32& server; UINT inactiveIcon; UINT activeIcon; diff --git a/win/winvnc/VNCServerService.cxx b/win/winvnc/VNCServerService.cxx index 0a0ed520..d2a994aa 100644 --- a/win/winvnc/VNCServerService.cxx +++ b/win/winvnc/VNCServerService.cxx @@ -108,14 +108,16 @@ HANDLE LaunchProcessWin(DWORD /*dwSessionId*/) if (GetSessionUserTokenWin(&hToken)) { ModuleFileName filename; - CharArray cmdLine; - cmdLine.format("\"%s\" -noconsole -service_run", filename.buf); + std::string cmdLine; + cmdLine = strFormat("\"%s\" -noconsole -service_run", filename.buf); STARTUPINFO si; ZeroMemory(&si, sizeof si); si.cb = sizeof si; si.dwFlags = STARTF_USESHOWWINDOW; PROCESS_INFORMATION pi; - if (CreateProcessAsUser(hToken, NULL, cmdLine.buf, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &si, &pi)) + if (CreateProcessAsUser(hToken, NULL, (char*)cmdLine.c_str(), + NULL, NULL, FALSE, DETACHED_PROCESS, + NULL, NULL, &si, &pi)) { CloseHandle(pi.hThread); hProcess = pi.hProcess; diff --git a/win/winvnc/VNCServerWin32.cxx b/win/winvnc/VNCServerWin32.cxx index 87258986..a243d95e 100644 --- a/win/winvnc/VNCServerWin32.cxx +++ b/win/winvnc/VNCServerWin32.cxx @@ -130,18 +130,17 @@ void VNCServerWin32::processAddressChange() { length += i->size() + 1; // Build the new tip - CharArray toolTip(length); - strcpy(toolTip.buf, prefix); + std::string toolTip(prefix); for (i=addrs.begin(); i!= addrs.end(); i=next_i) { next_i = i; next_i ++; - strcat(toolTip.buf, i->c_str()); + toolTip += *i; if (next_i != addrs.end()) - strcat(toolTip.buf, ","); + toolTip += ","; } // Pass the new tip to the tray icon vlog.info("Refreshing tray icon"); - trayIcon->setToolTip(toolTip.buf); + trayIcon->setToolTip(toolTip.c_str()); } void VNCServerWin32::regConfigChanged() { diff --git a/win/winvnc/winvnc.cxx b/win/winvnc/winvnc.cxx index ee4d94a5..2e705bf0 100644 --- a/win/winvnc/winvnc.cxx +++ b/win/winvnc/winvnc.cxx @@ -106,23 +106,23 @@ static void processParams(int argc, char** argv) { if (strcasecmp(argv[i], "-connect") == 0) { runServer = false; - CharArray host; + const char *host = NULL; if (i+1 < argc) { - host.buf = strDup(argv[i+1]); + host = argv[i+1]; i++; } else { AddNewClientDialog ancd; if (ancd.showDialog()) - host.buf = strDup(ancd.getHostName()); + host = ancd.getHostName(); } - if (host.buf) { + if (host != NULL) { HWND hwnd = FindWindow(0, "winvnc::IPC_Interface"); if (!hwnd) throw rdr::Exception("Unable to locate existing VNC Server."); COPYDATASTRUCT copyData; copyData.dwData = 1; // *** AddNewClient - copyData.cbData = strlen(host.buf); - copyData.lpData = (void*)host.buf; + copyData.cbData = strlen(host); + copyData.lpData = (void*)host; printf("Sending connect request to VNC Server...\n"); if (!SendMessage(hwnd, WM_COPYDATA, 0, (LPARAM)©Data)) MsgBoxOrLog("Connection failed.", true); @@ -152,12 +152,12 @@ static void processParams(int argc, char** argv) { } else if (strcasecmp(argv[i], "-status") == 0) { printf("Querying service status...\n"); runServer = false; - CharArray result; + std::string result; DWORD state = rfb::win32::getServiceState(VNCServerService::Name); - result.format("The %s Service is in the %s state.", - VNCServerService::Name, - rfb::win32::serviceStateName(state)); - MsgBoxOrLog(result.buf); + result = strFormat("The %s Service is in the %s state.", + VNCServerService::Name, + rfb::win32::serviceStateName(state)); + MsgBoxOrLog(result.c_str()); } else if (strcasecmp(argv[i], "-service") == 0) { printf("Run in service mode\n"); runServer = false; -- 2.39.5