Want to see what people are talking about? See the latest forum posts.
*/
*/

View \EXEMOD.C

Modify global variables in EXE or COM file

Submitted By: WEBMASTER
Rating: Not rated (Rate It)


/*
EXEMOD.C - Modify global variables in EXE or COM file

Kevin Dean
16 Kellythorne Drive
Don Mills, Ontario
Canada  M3A 2L4

March 27, 1990

Modifies global variables in initialized data segment of EXE or COM files.
Cannot modify global variables that are declared but not initialized as these
lie in the BSS segment of the program and are not in fact in the EXE image file
itself.

Copyright (c) 1990 by Kevin Dean

For Turbo C versions 2.0 and above.  This code is public domain.
*/



#include <dir.h>
#include <dos.h>
#include <errno.h>
#include <fcntl.h>
#include <io.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

#include <exemod.h>


/***/
/*
Name        exemodify

Function        Modifies static data in EXE or COM files.

Syntax    int exemodify(char *progname, int keepdt, [void *data1,
                           unsigned n1, [void *data2, unsigned n2, [ ... ]]]
                           NULL);

Prototype in    exemod.h

Remarks  exemodify modifies global variables in the initialized data
                segment of the current EXE or COM file.  In DOS versions 3.0
                and up, exemodify takes the program name from _argv[0].  In DOS
                versions below 3.0, exemodify searches the DOS path for the
                program passed in progname.

                If keepdt is true, then the original file date/time stamp is
                preserved.

                exemodify cannot modify global variables that are declared but
                not initialized as these lie in the BSS segment of the program
                and are not in fact in the EXE or COM image file itself.

                WARNING: Huge model programs treat uninitialized data the same
                as initialized data with values of 0 in that the uninitialized
                data is also written to the EXE file.  Because of the model,
                the Turbo C startup code does not initialize this data to 0.
                Since the compiler itself does not differentiate between
                initialized and uninitialized data in the huge model, neither
                can this module, and so any changes written to what was
                intended to be the uninitialized data segment in the huge model
                could have unpredictable results.

Return value    exemodify returns the number of data items successfully
                modified (which may not be the same as the number of items
                passed) or -1 in case of error (such as file not found or
                invalid EXE file format).

                In the event of an error, the global variable errno is set to
                one of the following:

                        ENOENT    No such file or directory
                        EMFILE    Too many open files
                        EACCES    Permission denied
                        EINVACC  Invalid access code
                        EINVFMT  Invalid format

Portability     exemodify is unique to DOS.
*/

int exemodify(const char *progname, int keepdt, ...)
{
char *pathptr;      /* Pointer to program path */
char _progname[MAXPATH];        /* Program name */
int retcode;            /* Function return code */
char ext[MAXEXT];              /* Program extension */
int progfile;         /* Program file handle */
int iscomfile;      /* True if program is a COM file */
struct exeheader exe;      /* EXE file header */
long filelen;         /* Program file length */
struct ftime dtstamp;      /* Program date/time stamp */
va_list datalist;              /* List of data items to be written to file */
char *data;               /* Pointer to current data item */
unsigned n;               /* Size of current data item */
long seeklen;         /* Seek length into program file */

if (_osmajor < 3)
  /* Search DOS PATH for program */
  if ((pathptr = searchpath(progname)) != NULL)
    strcpy(_progname, pathptr);
  else
    _progname[0] = 0;
else
  /* Program name is 0th parameter in DOS versions 3.0 and up */
  strcpy(_progname, _argv[0]);

/* Assume error */
retcode = -1;

if (_progname[0])
  {
  if ((progfile = open(_progname, O_RDWR | O_BINARY)) != -1)
    {
    iscomfile = fnsplit(_progname, NULL, NULL, NULL, ext) & EXTENSION && !strnicmp(ext, ".COM", 4);

    if (!iscomfile && (read(progfile, &exe, EXEH_SIZE) != EXEH_SIZE || exe.id != EXE_ID))
      /* File is not a COM file and does not have a valid EXE file header */
      errno = EINVFMT;
    else
      {
      /* Cannot write beyond end of file */
      filelen = filelength(progfile);

      if (keepdt)
        /* Save date/time stamp */
        getftime(progfile, &dtstamp);

      retcode = 0;
      va_start(datalist, keep_attribs);

      while ((data = va_arg(datalist, char *)) != NULL)
        {
        if (iscomfile)
          /* Seek length is data offset - PSP size */
          seeklen = FP_OFF(data) - 256;
        else
          /* Seek length is (data segment - (PSP + PSP size) + EXE size) * 16 + data offset */
          seeklen = ((unsigned long)(FP_SEG(data) - (_psp + 16) + exe.size) << 4) + (unsigned long)FP_OFF(data);

        n = va_arg(datalist, unsigned);

        if (seeklen + n <= filelen && lseek(progfile, seeklen, SEEK_SET) != -1L && write(progfile, data, n) == n)
          /* Seek and write was successful */
          retcode++;
        }

      va_end(datalist);

      if (keepdt)
        /* Restore date/time stamp */
        setftime(progfile, &dtstamp);
      }

    close(progfile);
    }
  }
else
  /* File not found */
  errno = ENOENT;

return (retcode);
}

corner
© 1996-2008 CommunityHeaven LLC. All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
North American business development: Nicolai Wadstrom. Publisher: Lars Hagelin.
Resource Listings