August 26th, 2003, 06:18 AM
reading into structure
I have been trying to convert an old utility from dos to win32 but have come unstuck when reading a file into a struct, It works fine when its in the original program but it doesnt work here. Are there any changes i should make or ways to debug and find out exactly what is going on.
int rdrctl; // record control word
char rname; // relation name
long ctlvalue; // security control value
unsigned lrsize; // logical record size
long notup; // # of tuples
long nodtup; // # of deleted tuples
char rfilename; // relation's filename
char cfm_filename; // filename of the view onto the relation
unsigned long rdescrip; // relation description info
if ((rdrr_fd = open(rdrr_file,O_BINARY|O_RDONLY)) == -1)
printf("Open_files error opening file %s\n",rdrr_file);
bytes_read = read(rdrr_fd, (char *)&rdrr_50, sizeof(struct rdrtype_50) );
if (bytes_read != sizeof(struct rdrtype_50))
printf("Determine_version error on initial read, errno = %d\n",errno);
if (rdrr_50.off_again_flags == 5) <-- it is this that is not satisfied when it should be
August 26th, 2003, 07:29 AM
Without going into a detailed reading of your code, off hand I would say your problem is due to padding. Different compilers pad data in memory (and for binary data the disk is memory) different ways. Thirty-two bit OSs like to have their data on 32 bit boundaries. Since DOS is a 16 bit OS, I would speculate that the original data is stored on 16 bit boundaries and therefore when read in by a 32 bit program the data is being screwed up. If this is your problem (I figure it at around 90%), then you will have to write your own parsing program to read in the old DOS file and stick it into a new structure. If you 'manually' write your structure out as binary (i.e., don't fwrite the structure, fwrite the individual elements of the structure on after another) then you can 'manually' read the structure back in, generally free from the boundary issues (but not free from big endian vs little endian issues). Binary structure files can often be screwed up if the reading is done by the exact same program compiled with a different compiler (that does the padding different). If you try to pass your binary file to a different OS (in your case) or worse to a different hardware platform (say Windows to Mac or Unix), you can wind up with pure gibberish. There are ways to store binary data in a platform independant way, but they are not trivial and can result in significant code bloat (look up ASN.1 to find a way that has been in use for decades).
August 26th, 2003, 03:54 PM
Not necessarily. He may be able to redefine the struct to use shorts instead of ints, ints instead of longs, and read the data that way. Alternatively, he can dig up his old dos developement tools and write a quick utility to read the data in like he used to, write it out in a more friendly format. That may not work be very feasible if he has large quantities of data, which I suspsect he does, but there may be some variant of that plan which would.
August 26th, 2003, 04:33 PM
What compiler are you using?
Most compilers allow the packing to be modified from the default, either globally by compiler option, or locally with #pragma directives. GCC uses attribute declarations to define packing (and many other things).
Note also that in the DOS version the members rdrctl, and lrsize would have been 16bit, but are 32bit in Win32, change these to short, and unsigned short respectively.
If all else fails, I'd create a function to pack the structure by reading the file as an array of bytes the size of the original DOS structure, and then programmatically interpret the array and assign values to the structure. The structure is not so large that this would be much trouble, but you will need to know the packing arrangement of the original DOS compiler. You could reverse engineer this by examining the old data files with a hex viewer.
[EDIT:] Sorry, that last paragraph was almost exactly what mitakeet suggested.
Packing and data sizes are probably the only problems. Byte ordering is not an issue between DOS and Win32, since that is CPU not OS dependant.
Last edited by clifford; August 26th, 2003 at 04:41 PM.
August 26th, 2003, 06:02 PM
thanks guys, but i actually fear that my problem may lie elsewhere. I am currnetly using the Borland 5.0 compiler and program. If i try to recompile the original code for the dos program and run it the same problem occurs so i think its is a setting in borland that is different than the (microsoft i think) compiler that my predecesor used. Does anyone know which settings these could be, i have tried with both signed and unsigned but this made little difference. So maybe my code was ok after all
August 26th, 2003, 06:08 PM
Does the original program still run? Can it translate the records? Do you know what the first record is supposed to look like? If so, writing a parser is not that much of a problem. If you don't you will have to guess by looking at the file in hex. The sizes of the various bits of your structure will give you clews on what to look for. I am not sure if the padding would be nulls or just random crap that happened to be in the structure as it was written (I lean toward the latter). The strings ought to be null terminated, so they may help point out some boundaries.
August 27th, 2003, 03:51 AM
Be sure you are building a genuine 16bit DOS executable and not a Win32 console mode executable or 32bit DOS extender executable. The latter two will generate 32bit code, and will exhibit the same problems described earlier. Note that the Borland compiler may produce different packing by default than the compiler used to generate original code. Also the original code may have been built with non-default packing set globally.
I still think it would be better to reverse engineer data generated by the old version to determine the exact offset and size of each field. Generate a file specification from this independent of C structure implementation, and code accordingly.