www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2000/03/25/03:54:29

From: "Ben Davis" <ben AT vjpoole DOT freeserve DOT co DOT uk>
Newsgroups: comp.os.msdos.djgpp
Subject: Problem with FSEXT
Date: Sat, 25 Mar 2000 01:34:02 -0000
Organization: Customer of Planet Online
Lines: 148
Message-ID: <8bht85$61a$1@news7.svr.pol.co.uk>
NNTP-Posting-Host: modem-214.fluvoxamine.dialup.pol.co.uk
X-Trace: news7.svr.pol.co.uk 953972805 6186 62.136.207.214 (25 Mar 2000 08:26:45 GMT)
NNTP-Posting-Date: 25 Mar 2000 08:26:45 GMT
X-Complaints-To: abuse AT theplanet DOT net
X-Newsreader: Microsoft Outlook Express 4.72.3110.5
X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3110.3
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

I'm using File System Extensions (FSEXT) as follows:

1. Install encrypted_file_handler() as 'open handler' at beginning of
program.
2. Install the same function as a file handler whenever a specific file
ENCRYPTED_FILENAME is opened.
3. Change the bytes read or written according to an encryption algorithm.

The function is included below.

The encrypted file happens to be 8001 bytes long. The encryption almost
works perfectly. Almost.

I use Allegro's packfile functions to save the file. THE LAST 11 BYTES ARE
NEVER ENCRYPTED, though they are indeed written to the file. My function
should be encrypting these bytes, and I have discovered it is never
receiving them. I inserted a byte count, and it only reached 7990.

I load the file in two ways later on. First, I read it without decompressing
(but still decrypting - not to be confused), using the standard libc file
functions. I do this in order to check whether the correct decryption key
was provided. ALL BYTES ARE PASSED TO MY FUNCTION, AND DECRYPTED (including
the last 11). This means these bytes become garbage as they weren't
encrypted in the first place. This affects the checksum, but does not cause
a crash as I don't use the data at this stage.

Finally I load the file using the packfile functions again, this time in
order to use the file. My game does not crash, nor get the last level wrong
or anything (it works perfectly), leading me to believe that THE SAME 11
BYTES ARE MISSED, giving me the original file. This may be so, but there's
still an error here that I'd like to find; and I need the checksum to be
constant.

As this only happens with the Allegro functions, I wondered whether they do
something which I don't. I checked, and all the file access occurs through
the following macros:

#define FILE_OPEN(filename, handle)             handle = open(filename,
O_RDONLY | O_BINARY, S_IRUSR | S_IWUSR)
#define FILE_CREATE(filename, handle)           handle = open(filename,
O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)
#define FILE_CLOSE(handle)                      close(handle)
#define FILE_READ(handle, buf, size, sz)        sz = read(handle, buf, size)
#define FILE_WRITE(handle, buf, size, sz)       sz = write(handle, buf,
size)
#define FILE_SEARCH_STRUCT                      struct ffblk
#define FILE_FINDFIRST(filename, attrib, dta)   findfirst(filename, dta,
attrib)
#define FILE_FINDNEXT(dta)                      findnext(dta)
#define FILE_ATTRIB                             ff_attrib
#define FILE_SIZE                               ff_fsize
#define FILE_NAME                               ff_name
#define FILE_TIME                               ff_ftime
#define FILE_DATE                               ff_fdate

I can't work out why this should be going on. Can anyone help?

Ben Davis

What did someone say about two initial underlines and "you will blow up"?
:-(

**************

Here is my function, encrypted_file_handler()...

static int encrypted_file_handler(__FSEXT_Fnumber n, int *rv, va_list args)
{
    static unsigned char efh_in_progress = 0;        /* used when recursion
is necessary */
    if (efh_in_progress) return 0;        /* return 0 causes normal action
to take place */
    switch (n) {
        case __FSEXT_open:
            {
                unsigned char *path;
                int attrib;
                path = va_arg(args, unsigned char *);
                if (stricmp(path, ENCRYPTED_FILENAME)) return 0;
                efh_in_progress = 1;
                attrib = va_arg(args, int);
                *rv = _open(path, attrib);        /* efh_in_progress=1
prevents infinite recursion */
                if (*rv >= 0) {
                    INITIALISE_ENCRYPTION_ALGORITHM();
                    /* install this handler for the file just opened */
                    __FSEXT_set_function(*rv, encrypted_file_handler);
                }
                efh_in_progress = 0;
                return 1;        /* indicates that we have already taken
care of open call */
            }
        case __FSEXT_read:
            {
                int fd;
                unsigned char *b, *e;
                size_t l;
                efh_in_progress = 1;
                fd = va_arg(args, int);
                b = va_arg(args, void *);
                l = va_arg(args, size_t);
                *rv = _read(fd, b, l);
                if (*rv > 0) {
                    /* decrypt data starting at b for *rv bytes */
                    e=b + *rv;
                    for ( ; b<e; b++) APPLY_DECRYPTION(*b);
                }
                efh_in_progress = 0;
                return 1;
            }
        case __FSEXT_write:        /* this doesn't need to be very
efficient! */
            {
                int fd;
                unsigned char *b, *e, x;
                size_t l;
                efh_in_progress = 1;
                fd = va_arg(args, int);
                b = va_arg(args, void *);
                l = va_arg(args, size_t);
                e = b+l;
                l = 0;
                for ( ; b<e; b++) {
                    x = *b;
                    /* encrypt byte x */
                    APPLY_ENCRYPTION(x);
                    if (_write(fd, &x, 1) != 1) break;
                    l++;
                }
                *rv = l;
                efh_in_progress = 0;
                return 1;
            }
        case __FSEXT_close:
            {
                int fd;
                fd = va_arg(args, int);
                __FSEXT_set_function(fd, 0);        /* remove the function
*/
                return 0;
            }
        default:        /* to prevent 'incomplete enum' warnings */
    }
    return 0;
}



- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019