Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
-Delphi/Pascal
-CBuilder/C++
-C#Builder/C#
-JBuilder/Java
-Kylix
Member Area
-Home
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Login/Logout
-Become a Member
-Why sign up!
-Newsletter
-Chat Online!
-Indexes NEW!!
Employment
-Build your resume
-Find a job
-Post a job
-Resume Search
Contacts
-Contacts
-Feedbacks
-Link to us
-Privacy/Disclaimer
Embarcadero
Visit Embarcadero
Embarcadero Community
JEDI
Links
Easy EXE attached data Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
18-Sep-03
Category
Files Operation
Language
Delphi 4.x
Views
247
User Rating
No Votes
# Votes
0
Replies
0
Publisher:
DSP, Administrator
Reference URL:
DKB
			Author: Christian Cristofori

Using resources to include files into your EXE is a great thing, but I prefer using 
another way...

Answer:

When you compiled your code, and you want to attach 1 file to your file just use 
this command line: 

COPY /B PROJECT1.EXE + DATA.TXT PROJECT2.EXE 

A file, called Project2.Exe will be created and it will contain first file with 2nd 
file attached. That doesn't compromise EXE and it will be still working. 

But: how to easly extract that file form the EXE? 

First of all, you should use this function: 
1   
2   function GetAttachedData(MS: TMemoryStream): boolean;
3   var
4     pMySelf: pChar;
5     IdX, SectionsCount: integer;
6     EXESize, EXEOriginalSize: cardinal;
7     SR: TSearchRec;
8     FS: TMemoryStream;
9     EXEName: array[0..MAX_PATH] of char;
10  begin
11    result := false;
12    if MS = nil then
13      exit;
14    try
15      MS.clear;
16      // Gets EXE/DLL filename.
17      fillchar(EXEName, sizeof(EXEName), #0);
18      getmodulefilename(HInstance, EXEName, MAX_PATH);
19      // Gets file size.
20      EXESize := 0;
21      if findfirst(EXEName, faAnyFile, SR) = 0 then
22      begin
23        EXESize := SR.size;
24        sysutils.findclose(SR);
25      end;
26      // Gets originalsize.
27      EXEOriginalSize := 0;
28      try
29        pMySelf := pointer(HInstance);
30        if PImageDosHeader(pMySelf).E_Magic <> $00004550 then
31          exit;
32        inc(pMySelf, PImageDosHeader(pMySelf)._lfanew);
33        if pDWord(pMySelf)^ <> $00004550 then
34          exit;
35        inc(pMySelf, sizeof(dword));
36        SectionsCount := PImageFileHeader(pMySelf).NumberOfSections;
37        inc(pMySelf, sizeof(TImageFileHeader) + sizeof(TImageOptionalHeader));
38        for IdX := 1 to SectionsCount do
39        begin
40          with PImageSectionHeader(pMySelf)^ do
41            if (PointerToRawData + SizeOfRawData) > EXEOriginalSize then
42              EXEOriginalSize := PointerToRawData + SizeOfRawData;
43          inc(pMySelf, sizeof(TImageSectionHeader));
44        end;
45      except
46        on e: exception do
47          EXEOriginalSize := 0;
48      end;
49      // If there's something attached...
50      if EXESize > EXEOriginalSize then
51      begin
52        FS := TMemoryStream.create;
53        try
54          try
55            // Read it...
56            FS.loadfromfile(EXEName);
57            FS.position := EXEOriginalSize;
58            // and return it in the stream.
59            MS.copyfrom(FS, EXESize - EXEOriginalSize);
60            result := true;
61          except
62            on e: exception do
63              result := false;
64          end;
65        finally
66          FS.destroy;
67        end;
68      end;
69    except
70      on e: exception do
71        result := false;
72    end;
73  end;
74  
75  //Then, you can use it like this: 
76  
77  procedure TForm1.Button1Click(Sender: TObject);
78  var
79    s: tmemorystream;
80  begin
81    s := tmemorystream.create;
82    try
83      if GetAttachedData(s) then
84        s.SaveToFile('output.txt');
85    finally
86      s.destroy;
87    end;
88  end;


That's all. You don't need to use constants, resources or anything else. 
Note that the code will work also if the EXE file is compressed with tools like UPX 
or similar. 
Thanks to the site U.N.D.U.http://www.undu.com/ for some code snippets.

			
Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10

 

Advertisement
Share this page
Advertisement
Download from Google

Copyright © Mendozi Enterprises LLC