Source Code of exe2com.

/*
exe2com-exe2binreplacementbyChrisDunford/CoveSoftware

usage:exe2com[/I]infile[outfile]

usageisthesameasexe2binexcept:
1.OutputdefaultstoCOMratherthanBIN
2.Binaryfixupoptionnotsupported
3.Checksumnotverified
4.Providesmoreusefulerrormessagesandawarningifa
COMfileisbeingcreatedwithinitialIP!=0x100
5./IswitchprovidesEXEfileinfoinsteadofconverting

Compilernotes:
ThissourcewaswrittenforMicrosoftCversion5.0.It
shouldbereasonablyportable.Watchoutforfseek();
whatitreturnsseemstovarywidelybetweencompilers.

TocompilewithMSC,use:

clexe2com.c(noswitchesnecessary)

Wehavecheckedthatthesource(asofversion1.04)compiles
withouterrorunderTurboC1.5.Itappearstooperatecorrectly,
butweranonlysomequicktests;theremaybesubtleerrorshere.

Theoriginalversionofthisprogramwasknockedtogetherinabout
anhourinresponsetotheremovalofEXE2BINfromthestandardDOS
distributiondisks.Improvements/correctionsareencouraged,but
pleasetrytocoordinatepublicreleasesthroughme.

Programdonatedtothepublicdomainbytheauthor.

cjd4/17/87


Versionhistory
---------------
Version1.0403/02/88(CJD)
Cleanedupsomeuglycodefromtheoriginalquickie.Added
/I(info)switch.Inpreviousversions,wedefinedan
errorcodefornonzeroCSbutdidn'tactuallycheckit;now
wedo.SourcewillnowcompileundereitherMicrosoftCor
TurboC.

Version1.0312/30/87(CJD)
C86versionconvertedtoMicrosoftC(5.0)byChris
Dunford.IncreasedsizeofI/Obufferto4Ktoimprove
speed;EXE2COM1.03istwiceasfastas1.02andisnow
slightlyfasterthanEXE2BIN.TheC86versionwillno
longerbedistributed.

Version1.0211/22/87
byChrisBlum(CompuServe76625,1041)
Fixforeven512-byteboundaryfilelosinglast512bytes.
AlsocorrectedsignonperrequestofChrisDunford(hisname
waslostinthetranslationtoTurboC).Version1.02
existedinbothTurboCandC86versions,althoughonly
theC86executablewas"officially"distributed.

Version1.01wasaTurboCconversion.

Version1.0004/17/87
OriginalC86versionbyChrisDunford

*/

#include<stdio.h>
#include<string.h>
#include<ctype.h>

/*Versioncoding*/
#defineMAJVER1
#defineMINVER0
#defineREVISION4

/*Conversionerrorcodes*/
#defineBADREAD0
#defineBADWRITE1
#defineBADSIG2
#defineHASRELO3
#defineHAS_SS4
#defineHAS_CS5
#defineBAD_IP6
#defineTOO_BIG7
/*Thismustbethelastcode*/
#defineUNKNOWN8

/*Definesizeofconsoleoutputbuffer*/
#defineCONBUFSIZ2048

/*
**Definestructureoffixed-formatpartofEXEfileheader
*/
structexe_header{
charexe_sig[2];/*EXEfilesignature:"MZ"*/
unsignedexcess,/*Imagesizemod512(validbytesinlastpage)*/
pages,/*#512-bytepagesinimage*/
relo_ct,/*Countofrelocationtableentries*/
hdr_size,/*Sizeofheader,inparagraphs*/
min_mem,/*Minrequiredmemory*/
max_mem,/*Maxrequiredmemory*/
ss,/*Stacksegoffsetinloadmodule*/
sp,/*InitialvalueofSP*/
cksum,/*Filechecksum*/
ip,/*InitialvalueofIP*/
cs,/*CSoffsetinloadmodule*/
relo_start,/*Offsetoffirstreloitem*/
ovl_num;/*Overlaynumber*/
}xh;

FILE*fi,/*Inputfilestream*/
*fo;/*Outputfilestream*/

charfin[129],/*Inputfilename*/
fon[129];/*Outputfilename*/

intinfo=0;/*Nonzeroif/Ifound*/

charbuf[CONBUFSIZ];/*printfI/Obuffer*/

chardefext[]=".com";/*Defaultoutputextension-changeifyouwant*/

unsignedlongcode_start,/*OffsetofprogramimageinEXEfile*/
code_size;/*Sizeofprogramimage,inbytes*/

/*Functionprototypes*/
voidinit(unsigned,char*[]);
voidread_hdr(void);
voiddisp_info(void);
voidconvert(void);
voiderr_xit(unsigned);
voidusage(void);

/*
**programmainline
*/
main(argc,argv)
unsignedargc;
char*argv[];
{
init(argc,argv);
read_hdr();
if(info)
disp_info();
else
convert();
}


/*
**Initialize-parsearguments,getfilenames,open/createfiles
*/
voidinit(argc,argv)
unsignedargc;
char**argv;
{
charc,*cp;
inti;

/*Setupbufferedoutput,displaylogo*/
setvbuf(stdout,buf,_IOFBF,CONBUFSIZ);
printf("exe2com%u.%u%ubyChrisDunford/TheCoveSoftwareGroup/n",
MAJVER,MINVER,REVISION);

/*Getarguments*/
cp=*(++argv);
for(i=1;i< argc; i++) {
while ( (cp = strchr (cp, '/')) != (char *) NULL) {
*cp++ = '/0';
c = *cp++;
switch (toupper (c)) {
case 'I':
info = 1;
break;
default:
usage ();
}
}

if (**argv)
if (fin[0] == '/0')
strcpy (fin, strlwr (*argv));
else if (fon[0] == '/0')
strcpy (fon, strlwr (*argv));
else
usage ();

cp = *(++argv);
}

/* Check to ensure that an input filename was found *.
if (fin[0] == '/0') usage ();

/* If the input file has no extension, add .EXE */
if (strchr (fin, '.') == (char *) NULL)
strcat (fin, ".exe");

/* Copy input name to output if unspecified */
if (fon[0] == '/0')
strcpy (fon, fin);

/* Check output extension--change EXE to COM, or add COM */
if ((cp = strchr (fon, '.')) == (char *) NULL)
strcat (fon, defext);
else if (strcmp (cp, ".exe") == 0)
strcpy (cp, defext);

/* Try to open input file */
if ((fi = fopen (fin, "rb")) == (FILE *) NULL) {
fprintf (stderr, "exe2com: can't find input file %s/n", fin);
exit (1);
}

/* Try to create output file, if INFO not requested */
if (!info)
if ((fo = fopen (fon, "wb")) == (FILE *) NULL) {
fprintf (stderr, "exe2com: can't open output file %s/n", fin);
exit (1);
}
}


/*
** usage display
*/
void usage (void)
{
fprintf (stderr, "usage: exe2com [/I] infile [outfile]/n");
exit (1);
}


/*
** Read and check the EXE file header
*/
void read_hdr(void)
{
char *cp;

/* Read the formatted portion of the header */
if (!fread (&xh, sizeof (struct exe_header), 1, fi))
err_xit (BADREAD);

/* Check for "MZ" signature */
if (strncmp (xh.exe_sig, "MZ", 2))
err_xit (BADSIG);

/* Compute offset of program image in module, and program size.
**
** The program size is computed as follows; it cannot exceed 64Kbytes:
**512*(#EXEpages-1)
**+validbytesinlastEXEpage
**-offsetofprogramimageinEXEfile
**
**NotethatiftheIPisnonzero,wewillskipthefirst
**IPbytesoftheprogramimage,andcopyIPbytesfewer
**thantheactualsize.
*/
code_start=((unsignedlong)xh.hdr_size)<< 4;
code_size = (unsigned long) (xh.pages-1) * 512
+ (xh.excess ? xh.excess : 512) /* fixed 11/19/87 - CJB */
- code_start;

/* Don't check anything else if /I requested */
if (info) return;

/* Check header; to be convertible, must have:
** -- no relocatable items
** -- no stack segment
** -- no code segment
** -- IP == 0 or 100
** -- code size < 65536
*/
if (xh.relo_ct)
err_xit (HASRELO);
if (xh.ss || xh.sp)
err_xit (HAS_SS);
if (xh.cs)
err_xit (HAS_CS);
if (xh.ip != 0 && xh.ip != 0x100)
err_xit (BAD_IP);
if (code_size ><?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><chmetcnv w:st="on" unitname="l" sourcevalue="65536" hasspace="False" negative="False" numbertype="1" tcsc="0">65536L</chmetcnv>)
err_xit(TOO_BIG);

/*IssueawarningifCOMfileandIP!=0x100*/
if(!strcmp(strchr(fon,'.'),".com")&&xh.ip!=0x100)
fprintf(stderr,"exe2comwarning:COMfile,initialIPnot100H/n");

}


/*
**/ioutput:displayEXEfileinfo
*/
voiddisp_info(void)
{
char*cp;
unsignedlongk;

cp=strrchr(fin,'//');
if(!cp)cp=strchr(fin,':');
cp=cp?cp++:fin;
printf("/n%-20s(hex)(dec)/n",cp);

k=(unsignedlong)(xh.pages-1)*512+(xh.excess?xh.excess:512);
printf("EXEfilesize%5lX%7lu/n",k,k);

printf("EXEheadersize(para)%4X%7u/n",xh.hdr_size,xh.hdr_size);

putchar(code_size><chmetcnv w:st="on" unitname="l" sourcevalue="65536" hasspace="False" negative="False" numbertype="1" tcsc="0">65536L</chmetcnv>?'*':'');
printf("Programimagesize(bytes)%5lX%7lu/n",code_size,code_size);

k=(unsignedlong)xh.min_mem*16+code_size;
printf("Minimumloadsize(bytes)%5lX%7lu/n",k,k);

printf("Minallocation(para)%4X%7u/n",xh.min_mem,xh.min_mem);

printf("Maxallocation(para)%4X%7u/n",xh.max_mem,xh.max_mem);

putchar(xh.cs||(xh.ip!=0x100)?'*':'');
printf("InitialCS:IP%04X:%04X/n",xh.cs,xh.ip);

putchar(xh.ss||xh.sp?'*':'');
printf("InitialSS:SP%04X:%04X%7u(stacksize)/n",xh.ss,xh.sp,xh.sp);

putchar(xh.relo_ct?'*':'');
printf("Relocationcount%4X%7u/n",xh.relo_ct,xh.relo_ct);

printf("Relotablestart%04X%7u/n",xh.relo_start,xh.relo_start);

printf("EXEfilechecksum%04X%7u/n",xh.cksum,xh.cksum);

printf("Overlaynumber%4X%7u/n",xh.ovl_num,xh.ovl_num);

printf("*=thisitempreventsconversiontoBIN/COM/n");
}

/*
**Convertthefile.Nothingtodo,really,otherthan
**readingtheimage(whichfollowstheheader),and
**dumpingitbackouttodisk.
*/
voidconvert(void)
{
#defineBUFSIZE16384
staticcharbuffer[BUFSIZE];/*Forcesbufferoutofprogramstack*/
unsignedbsize;

/*Seektostartofprogramimage,skippingIPbytes*/
if(fseek(fi,code_start+xh.ip,0))
err_xit(BADREAD);

/*Readblocksandcopytooutput*/
for(code_size-=xh.ip;code_size;code_size-=bsize){

/*Setcountofbytestoread/write*/
bsize=code_size>BUFSIZE?BUFSIZE:code_size;

/*Readandwriteblock*/
if(!fread(buffer,bsize,1,fi))
err_xit(BADREAD);
if(!fwrite(buffer,bsize,1,fo))
err_xit(BADWRITE);
}

/*Alldone,closethetwofiles*/
fclose(fi);
fclose(fo);
}


/*
**Displayanerrormessage,deleteoutputfile,exit.
*/
voiderr_xit(code)
unsignedcode;
{
staticchar*msg[UNKNOWN+1]={
"errorreadingEXEheader",
"errorwritingoutputfile",
"invalidEXEfilesignature",
"EXEhasrelocatableitems",
"EXEhasstacksegment",
"EXEhasnonzeroCS",
"IPnot0or100H",
"programexceeds64K",
"unknowninternalerror"
};

if(code>UNKNOWN)code=UNKNOWN;
fprintf(stderr,"exe2com:%s,can'tconvert/n",msg[code]);

/*Closetwofilesanddeletepartialoutput*/
fclose(fi);
fclose(fo);
unlink(fon);

/*Exitwitherrorlevel1*/
exit(1);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值