#include <io.h>
#include <fcntl.h>
#define EOF -1
#define buffersize 0x200
typedef struct
{
 unsigned int signature;
 unsigned int partpage;
 unsigned int pagecount;
 unsigned int relocount;
 unsigned int headersize;
 unsigned int minmem;
 unsigned int maxmem;
 unsigned int reloss;
 unsigned int exesp;
 unsigned int chksum;
 unsigned int exeip;
 unsigned int relocs;
 unsigned int tableoffset;
 unsigned int overlay;
} exeheader;
exeheader header;
int count,infile,outfile;
char buffer[buffersize];
char *outname,*line,*outline;
void usage()
{
 puts("Usage: EXEBIN Source{.com|.bin|.exe|} Destination{.exe|.bin|.com} {BIN|EXE}\nBIN - Convert the EXE to BIN.\nEXE - Convert the BIN to EXE.");
 exit(0);
}
void msg(char *message)
{
 if(infile!=EOF)close(infile);
 if(outfile!=EOF)close(outfile);
 puts(message);
}
void error(char *message)
{
 msg(message);
 if(outfile!=EOF)unlink(outname);
 exit(0);
}
void cannotread()
{
 error("Cannot read from the source file.");
}
void cannotwrite()
{
 error("Cannot write to the destination file.");
}
void copyfile()
{
 outline=strcpy(outline,"Copying. Source file size is: ");
 ultoa(filelength(infile)-tell(infile),line,10);
 strcat(outline,line);
 puts(strcat(outline," bytes. Please waith..."));
 while(1)
 {
  if((count=read(infile,buffer,buffersize))==EOF)cannotread();
  if(count==0)break;
  if((count=write(outfile,buffer,count))==EOF)cannotwrite();
 }
 msg("File is succefully converted!");
 exit(0);
}
void main(int argc,char *argv[])
{
 puts("EXE to BIN & BIN to EXE converter.\n(C) Copyright by: Sandul Y. V.\n(R) Wednesday, 20 March 2002 year.\nAll rights reserved.\n*** The FreeWare. ***");
 if(argc!=4)usage();
 infile=EOF;
 outfile=EOF;
 strcpy(outname,argv[2]);
 if((infile=open(argv[1],O_BINARY))==EOF)error("Cannot open the source file.");
 if((outfile=open(argv[2],O_BINARY+O_CREAT))==EOF)error("Cannot open the destination file.");
 strupr(argv[3]);
 if(strcmp(argv[3],"BIN")==0)
 {
  if((count=read(infile,&header,sizeof(header)))==EOF)cannotread();
  if(header.signature!=0x5a4dL)error("Source file is not in EXE format.");
  if(header.relocount!=0)error("Source file contains relocatable elements.");
  if(header.exeip!=0x100)error("The entry point in the source file is not 256.");
  if(header.tableoffset!=0x1c)puts("Source file might be using enhanced EXE format.");
  if(header.reloss!=0||header.exesp!=0)puts("Source file might contain predefined stack.");
  if(lseek(infile,(header.headersize*16)+0x100,SEEK_SET)==EOF)error("Cannot seek in the source file.");
  copyfile();
 } else if(strcmp(argv[3],"EXE")==0)
 {
  header.signature=0x5a4d;
  header.partpage=(filelength(infile)+32)%512;
  header.pagecount=((filelength(infile)+32)/512)+1;
  header.relocount=0;
  header.headersize=2;
  header.minmem=0;
  header.maxmem=0xffff;
  header.reloss=0xfff0;
  header.exesp=0xfffe;
  header.chksum=0;
  header.exeip=0x100;
  header.relocs=0xfff0;
  header.tableoffset=0x1c;
  header.overlay=0;
  memset(buffer,0,sizeof(header)+4);
  memcpy(buffer,&header,sizeof(header));
  if(write(outfile,buffer,sizeof(header)+4)<sizeof(header)+4)cannotwrite();
  copyfile();
 } else usage();
}
