Determining exe size

I'd like to be able to determine an exe's size based on information in the header; so I can read the rest of the data from the file (I'm going to append data to the exe)
I'm sure I've seen how to do this somewhere.. just cant find it.
LVL 1
delphiexpertAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

intheCommented:
you know about GetFileSize() api ?
0
intheCommented:
i cut this from larger example but it shows how to call it:

procedure TForm1.FileListBox1Change(Sender: TObject);
var
  Security: TSecurityAttributes;        // security attributes for the file
  hFile: Integer;                       // holds the file handle
  FileInfo: TByHandleFileInformation;   // holds the file information
  Intermediate: TFileTime;              // holds a file time
  SystemTime: TSystemTime;              // holds the converted file time
  FileType: DWORD;                      // holds the file type
  AMPM: string;                         // morning/evening indicator
begin
  {clear the status bar}
  StatusBar1.SimpleText:= '';

  {initialize the security information}
  Security.nLength:=SizeOf(TSecurityAttributes);
  Security.bInheritHandle:=FALSE;

  {open the selected file for reading}
  hFile:=CreateFile(PChar(FileListBox1.FileName), GENERIC_READ, 0, @Security,
                    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if (hFile <> INVALID_HANDLE_VALUE) then
  begin
    {retrieve the file information}
    GetFileInformationByHandle(hFile,FileInfo);


    {display the file size}
    Label4.Caption:=IntToStr(GetFileSize(hFile, nil))+ ' bytes';
0
BSamsonCommented:
It sounds like you want to create a stub EXE that you can append other data to.  The EXE size isn't stored in the EXE header, the only way I know to do this is to write two programs.

One program is your EXE stub application to which you intend to append your data.

The code for your stub should open it's own EXE file and perform a file seek to a predefined file position ( this is where your other short program comes in ).

Once at your predefined location you can read your extended data.

The other application you need to write is a small program to taek your EXE stub program and your extended data and concatenate them into a new EXE file.

Note  You'll need to compile your EXE stub application with some arbitary figure for the predefined location, then once it's compiled, note down the files size of the Stub EXE, go back into the code for the stub EXE and set the predefined location to the filesize you just noted down,  now recompile the stub ( now with the correct location value ) make sure that the EXE stub file size hasn't changed from the value you noted down, then run your second application to concatenate the stub and the extended data into a single EXE.

A bit painful I know..

Brian
0
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

delphiexpertAuthor Commented:
D'oh, thats the way I was going to do it but I was hoping there was a better way

I'll leave this one open for a bit in case there is...

BTW there's no need to write an app to make the two files into one:
copy /b stub.exe+data.dat output.exe
works fine

0
BSamsonCommented:
Of course..

In the past, I automated the whole process so it would compile, check the size, edit the source file and recompile.

If you think about it, there isn't anyway that the size could be held in the EXE header, because until the file is created the size isn't known.

All the Best
Brian
0
ahalyaCommented:
Hello Delphi Expert,

I have created a similar "self extracting" EXE.  I do use an identifier to find the location of my data file within the EXE.  By doing this I don't have to worry about the size of the EXE or the attachemnts. All the required info will be self contained withing the "Self extracting" exe.

I can attach several files (including other EXEs :-) and at the end i write a small record with the toal size of the data files.  [Ofcouse I have a seperate exe file that calls my "AttachFiles" and "FinaliseAttachments" procedures to create the new Self Extracting EXE (by appending the DataRecords & Files to the stub EXE; My stub EXE is only 15k in size, btw)

The stub EXE first reads the "Finalised Data Record" to findout the info about the file contained within itself. It then can extract files (even selectively, if you want to).

I have copied a few of my procedures, that you may find useful.




const FileDataHeader : string[10] = '*FileData*' ;
      FinalizeHeader : string[10] = '*FileInfo*' ;
      CtrlZ         : char = ^Z                 ;

function  AttachFile(ExeName, DataFileName:string):boolean;

var f    : file ;
    size : DWord;
    data : pointer;

begin
AttachFile := false;
Size := FileSizeof(DataFileName);
AssignFile(f, DataFileName);

try
   GetMem(data, size);
   FileMode := 0; //Read only
   reset(f,1);
   BlockRead(f, Data^,Size);

   assign(f,ExeName);
   FileMode := 2        ;{Allow Read and Write}
   reset(f,1);
   Seek(f,FileSize(f));

   BlockWrite(f,FileDataHeader,SizeOf(FileDataHeader));
   FileInfo.FileName := ExtractFileName(DataFileName);
   FileInfo.FileSize := Size;

   BlockWrite(f, FileInfo, sizeof(FileInfo));
   BlockWrite(f, Data^,Size);
   BlockWrite(f,CtrlZ,1);
   Result := true;
finally
   FreeMem(Data);
   close(f);
   end;
end;


function FinaliseAttachments(ExeName:string; TotalLength:integer):boolean;

var f    : file ;
    size : DWord;
    data : pointer;

begin
result := false;
try
   AssignFile(f,ExeName);
   FileMode := 2        ;{Allow Read and Write}
   reset(f,1);
   Seek(f,FileSize(f));

   BlockWrite(f, FinalizeHeader, SizeOf(FinalizeHeader));
   BlockWrite(f, TotalLength ,   Sizeof(TotalLength));
   BlockWrite(f,CtrlZ,1);
   Result := true;
finally
   CloseFile(f);
   end;
end;

function GetAttachSize(ExeName:string):integer;

var f    : file ;
    size : DWord;
    data : pointer;

begin
result := 0;
try
   AssignFile(f,ExeName);
   FileMode := 0; //read only
   reset(f,1);

   Seek(f,FileSize(f)-Sizeof(integer)-1);
   BlockRead(f, Size , Sizeof(Size));
   Result := size;
finally
   CloseFile(f);
   end;
end;


//******************************************
//Here is the code from my stub EXE that extracts all files:
//******************************************

   StartPos := GetAttachSize(ExeName);
   try
     AssignFile(fin, ExeName);
     FileMode := 0;//read only
     reset(fin,1);
     Overhead := SizeOf(FileDataHeader) + SizeOf(TFileInfo) + SizeOf(CtrlZ);

     repeat
      Seek(fin, FileSize(fin) - StartPos - Sizeof(FinalizeHeader) - Sizeof(integer)-1);
      BlockRead(fin ,Buffer,SizeOf(FileDataHeader));
      if (Buffer = FileDataHeader) then
         begin;
         BlockRead(fin, FileInfo, sizeof(FileInfo));
         s := Dir + FileInfo.FileName;
         StartPos := StartPos - FileInfo.FileSize - OverHead;
         GetMem(Data, FileInfo.FileSize);
         try
           BlockRead(fin,Data^,FileInfo.FileSize);
           AssignFile(fout, s);//Dir contains dir & filename.
           FileMode := 1;
           ReWrite(fout, 1);
           BlockWrite(fout, Data^, FileInfo.FileSize);
         finally
           FreeMem(Data);
           CloseFile(fout);
         end;
         if IsEXEFile(s) then ExecExe(s);
         end;
     until (Buffer <> FileDataHeader);
   finally
    CloseFile(fin);
    end;
   end;
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.