Storing C++-struct in file - problem when adding new item in struct

Hi,
I have received an application that stores some properties in a file. The existing struct looks like this:

struct TData 
{
 UINT uSizeIncludingStrings;
 // copy of Telnet data struct
 UINT uSize;
 // basic properties:
 TCHAR szHost[MAXHOSTLEN];  //defined in Sshconfig
 UINT iPortNr;
 TCHAR szTermType[MAXTERMTYPE];
 // login properties:
 BOOL bTelnetLogin;
 TCHAR szUserName[MAXUSERNAME];
 BOOL bDetectUserName;
 BOOL bDetectPassWord;
 TCHAR szDetectUserName[MAXDTCTLEN];
 TCHAR szDetectPassWord[MAXDTCTLEN];
 // advanced options:
 BOOL bReplNull;
 TCHAR cNullChar;
 BOOL bFilterCR;
 BOOL bAddLF;
 BOOL bTransRel;
 BOOL bFilterXonXoff;
 BOOL bDetectDomain;
 TCHAR szDetectDomain[MAXDTCTLEN];
 TCHAR szDomain[MAXDOMAIN];
 char  *ciphers;
 char  *macs;
 int  authentication; };

The two char pointers ciphers and macs seem to be something that would not work because storing a pointer will not store anything else but the pointer itself and not the value but this is not the case here. When I open the property file I can read the values that were clicked in the checkboxes in the application. Some values seem to be human readable and some not in the rest of the file. The values ciphers and macs seem to be "enclosed" in some kind of block starting with STR_HEAD_VER_5 and ending with END_STR. This block also seem to be dynamically sized since there can be different numbers of ciphers and macs inside this block.

The problem is now that there is a need for adding another item in the struct and store it in the file. I was going to add a char* at the end as for ciphers and do the coding like the one handling ciphers and macs. It looks like this afterwards:

struct TData 
{
 UINT uSizeIncludingStrings;
 // copy of Telnet data struct
 UINT uSize;
 // basic properties:
 TCHAR szHost[MAXHOSTLEN];  //defined in Sshconfig
 UINT iPortNr;
 TCHAR szTermType[MAXTERMTYPE];
 // login properties:
 BOOL bTelnetLogin;
 TCHAR szUserName[MAXUSERNAME];
 BOOL bDetectUserName;
 BOOL bDetectPassWord;
 TCHAR szDetectUserName[MAXDTCTLEN];
 TCHAR szDetectPassWord[MAXDTCTLEN];
 // advanced options:
 BOOL bReplNull;
 TCHAR cNullChar;
 BOOL bFilterCR;
 BOOL bAddLF;
 BOOL bTransRel;
 BOOL bFilterXonXoff;
 BOOL bDetectDomain;
 TCHAR szDetectDomain[MAXDTCTLEN];
 TCHAR szDomain[MAXDOMAIN];
 char  *ciphers;
 char  *macs;
 int  authentication;
         char             *key;
 };

So far so good but the problem showed up when upgrading from the old application using the old struct in the property files. When starting the upgraded application with the new struct declared in the program some properties from the file were not read and you needed to enter them again and save and then it looks fine.

When debugging the new code reading an old property file I could see that there was a check done using sizeof(TData) to set the pointer in the file. Due to the increased size when adding the key item in the struct it steps to far. The check compares that the pointer points to the string STR_HEAD_VER_5(which is hardcoded in the code) in the file before reading the data within this block and then END_STR when finished. If the pointer in file does not point to the STR_HEAD_VER_5-string the reading is interrupted and an error message saying that the file is corrupt is received. When debugging I could see that the pointer pointed to HEAD_VER_5 instead which is not STR_HEAD_VER_5 and thus the reading is interrupted and some properties are not read.

My questions are now:

  • Is there some common used technique, method, way to handle a problem like this so the operator does not need to enter the values again and can use the old property files and when saving the properties in the upgraded version and then get the new property file?

Regards,
Kalle

You are mistaken. You cannot store "char *" in a file this way. You are storing pointers which, when you get them back, happen to point to some valid location in memory, but no mystical translation is happening -- a pointer is stored as 4 or 8 bytes, the data you wanted to store was never stored.

You must use fixed-size arrays like everything else.

Agreed with Corona, and I was going to make the same statement, but not seeing the rest of the code, and under the assumption it works, I figured maybe it was memory mapping the file to some fixed address location. That'd allow the pointer values to be stored and actually work so long as they only pointed to an address within the memory mapped region.

That said, I have no idea if the code is actually doing this. And, I must admit, for a properties file it's fetched.

As for the OP, I think you're generally misguided regarding what the code is doing. That struct is unlikely to be stored directly in the file. I'd dig a little deeper in the code and figure out what is reading and writing the file's data.

Better, why don't you just post what the file looks like; with that information we could probably immediately tell you whether or not that exact structure is stored verbatim in the file.