Sorry, I just havent been able to get a GetLastError() function to return anything.
What do you mean "not return anything?"
Code:
if (mFd == INVALID_HANDLE_VALUE)
{
DWORD dwError = GetLastError();
printf("The value of the error code is %d\n", dwError);
}
That is all we have been waiting for all this time. What is the error value?
In general:
Code:
if ( ThisFunctionCallReturnedFailure )
{
DWORD dwError = GetLastError( );
// dwError now has the reason code for why the function failed
}
That is what your original code was missing -- you never checked at all for the reason code for the failure. All you did was check for failure, and all we asked you to do is go further and check the reason for the failure by calling GetLastError(). That doesn't sound complex to me.
I am a complete newb to programming, but unfortunately, have been handed a project that is dealing with a fairly complex program that was downloaded. So most of the code I have posted, I did not actually do. Just trying to get this program to run properly ASAP
What we asked you to do has nothing to do with the size or complexity of the program.
All we wanted was you to make a single function call, GetLastError() and see what value is returned, instead of being in the dark as to why CreateFile fails. If you can't do that, then may I suggest you get someone else to finish your program, since what we asked is the simplest of things.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; September 9th, 2010 at 12:26 PM.
Sorry, I just havent been able to get a GetLastError() function to return anything.
Post the code that you written that shows us the GetLastError( ) calls. You need to call GetLastError immediately after an error occurs in another api call; otherwise it doesn't work. See the CreateFileA example that Victor posted a while ago.
...
Just trying to get this program to run properly ASAP[/QUOTE]The folks replying here are trying to help you. What you need to do is do what they suggest. It's also helpful if you post back code of what you've done rather than trying to describe what you think you did.
For example, you mentioned that you haven't been able to get GetLastError( ) to return anything. Without seeing the code, we can only guess where you put it or how you called it. If you post the code, we can immediately spot any errors.
That is saying that it cannot find the specified file correct? So I know that should be self explanatory, but can you explain to me what file it is talking about and what to do to correct this?
Last edited by wklove2003; September 10th, 2010 at 11:21 AM.
That is saying that it cannot find the specified file correct? So I know that should be self explanatory, but can you explain to me what file it is talking about and what to do to correct this?
Who knows what file it's talking about when you haven't included the code.
How come you haven't posted the code after being asked several times to do so? Do you actually read the replies?
Why not also print out the port along with the error code so you know what path is failing?
You're also just blindly retrying and don't check the GetLastError value on the first attempt. Maybe your error is something different than with the 2nd attempt?
#ifndef STRING_BUFFER_HPP
#define STRING_BUFFER_HPP
/*
* A simple extensible string that can be appended to. The memory will be reused
* since it maintains its length. The string buffer also supports setting a timestamp
* that will be prepended to the string once some data is appended.
*
* Currently allocating in 1k increments.
*/
class StringBuffer
{
protected:
char *mBuffer; /* A resizable character buffer */
size_t mSize; /* The allocated size of the string */
size_t mLength; /* The length of the string */
char mTimestamp[64];
public:
StringBuffer(const char *aString = 0);
~StringBuffer();
operator const char *() { return mBuffer; }
const char *append(const char *aString);
const char* operator<<(const char *aString) { return append(aString); }
void reset();
void timestamp();
size_t length() { return mLength; }
};
#endif
Any ideas? It seems fine to me, but I honestly do not know.
#ifndef SERIAL_HPP
#define SERIAL_HPP
class Serial {
public:
class SerialError
{
private:
char mMessage[1024];
public:
SerialError(const char *aMessage);
const char *message() const { return mMessage; }
};
private:
protected:
/* Descriptor (tty or socket) */
#ifdef WIN32
HANDLE mFd;
#else
int mFd;
#endif
/* Flag debug */
bool mDebug;
/* TCP port */
int mPort;
/* Device: "/dev/ttyS0", "/dev/ttyUSB0" or "/dev/tty.USA19*"
on Mac OS X for KeySpan USB<->Serial adapters this string
had to be made bigger on OS X as the directory+file name
was bigger than 19 bytes. Making it 67 bytes for now, but
OS X does support 256 byte file names. May become a problem
in the future. */
#ifdef __APPLE_CC__
char mDevice[64];
#else
char mDevice[16];
#endif
/* Bauds: 9600, 19200, 57600, 115200, etc */
int mBaud;
/* Data bit */
unsigned char mDataBit;
/* Stop bit */
unsigned char mStopBit;
/* Parity: "even", "odd", "none" */
char mParity[5];
/* In error_treat with TCP, do a reconnect or just dump the error */
bool mErrorHandling;
/* IP address */
char mIp[16];
#ifndef WIN32
/* Save old termios settings */
struct termios mOldTios;
#endif
bool mConnected;
private:
int read(char *aBuffer, int len);
int write(const char *aBuffer, int len);
public:
Serial(const char *aDevice,
int aBaud, const char *aParity, int aDataBit,
int aStopBit, bool aDebug = false);
~Serial();
bool debug() { return mDebug; }
bool connected() { return mConnected; }
bool connect();
bool disconnect();
int readUntil(const char *aUntil, char *aBuffer, int aLength);
int write(char *aBuffer);
bool flushInput();
};
#endif
Serial.cpp
Code:
#include "internal.hpp"
#include "serial.hpp"
#include <windows.h>
#include <strsafe.h>
Serial::SerialError::SerialError(const char *aMessage)
{
strncpy(mMessage, aMessage, 1023);
mMessage[1023] = '\0';
}
Serial::Serial(const char *aDevice,
int aBaud, const char *aParity, int aDataBit,
int aStopBit, bool aDebug)
{
mBaud = aBaud;
strncpy(mDevice, aDevice, sizeof(mDevice) - 1);
mParity[sizeof(mDevice) - 1] = '\0';
strncpy(mParity, aParity, sizeof(mParity) - 1);
mParity[sizeof(mParity) - 1] = '\0';
mDataBit = aDataBit;
mStopBit = aStopBit;
mDebug = aDebug;
#ifdef WIN32
mFd = INVALID_HANDLE_VALUE;
#else
mFd = -1;
#endif
mConnected = false;
}
Serial::~Serial()
{
disconnect();
}
int Serial::readUntil(const char *aUntil, char *aBuffer, int aLength)
{
if (!mConnected)
{
printf("Trying to read when not connected");
return -1;
}
if (mDebug)
printf("Reading upto %d bytes or we get a match\n", aLength, aUntil);
int len = 0, count = 0;
char *cp = aBuffer;
const char *match = aUntil;
do
{
int ret = read(cp, 1);
if (ret == -1)
{
throw SerialError("Couldn't read");
}
if (ret == 0)
{
usleep(10 * 1000); // 10 msec
if (count++ > 100)
{
printf("Read timed out\n");
return -1;
}
}
else
{
count = 0;
//printf("Received: %d == match: %d\n", *cp, *match);
if (*match == *cp)
match++;
else
match = aUntil;
// See if we can match the beginnig of the string again.
if (*match == *cp)
match++;
//printf("Match now: %d\n", *match);
cp++;
len++;
}
} while (len <= aLength && *match != '\0');
*cp = '\0';
if (mDebug)
printf("Read returned: %d - '%s'\n", len, aBuffer);
return len;
}
int Serial::write(char *aBuffer)
{
if (mDebug)
printf("Writing '%s'\n", aBuffer);
int ret = write(aBuffer, (int) strlen(aBuffer));
if (ret < 0)
throw SerialError("Couldn't write");
if (mDebug)
printf("Write returned: %d\n", ret);
return ret;
}
bool Serial::flushInput()
{
char buffer[2];
int ret;
do
{
ret = read(buffer, 1);
if (ret < 0)
throw SerialError("Couldn't read");
} while (ret > 0);
return true;
}
#ifdef WIN32
#include "serial.win32.cpp"
#else
#include "serial.unix.cpp"
#endif
Is this what you were looking for? Is that setting mDevice, its hard for me to understand it to be honest
What is mDevice declared as? How big is that array? Is it big enough to fit all of these characters? I see it is declared as an array of 64 (or 16) characters. What if there are more characters? What do you do then?
In general, your code is very faulty, as it does no checking if there is enough room for all of those strings. It is a classic example of how a buffer can be overrun, and therefore exploited by hackers.
Basically, you have a 'C' program, not a C++ program. Yes, you have some C++ syntax thrown in here and there, but it is basically a 'C' program. It does not use anything of C++ in terms of safety (buffer overruns).
Regards,
Paul McKenzie
Last edited by Paul McKenzie; September 10th, 2010 at 02:23 PM.
If you are using a version of Visual C++ that hasn't been written 2 decades ago (i.e. not VC6), just right click on mDevice and choose "Go to declaration".
Bookmarks