: : : : : Hi! I need help because I have a big problem. I want to write a Delphi program that creates new *.exe and *.dll files in C:\WINDOWS and C:\WINDOWS\SYSTEM (extracts them). These exe and dll files aren't written under Delphi. So I want to put them in my program but I don't know how.
: : : : :
: : : : It is perhaps easier and recommended to use an InstallShield or similar program for that, but here's how to code such a program.
: : : : You can safely add new resources to the end of the program, so putting them into the program isn't much problem. The biggest problem is getting them out again. For this you'll need to compiled program size without the additions, since that is the beginning of the data files. The easiest way of setting that data at the end of all the data. You'll also need to include the size of each datafile, which is best placed directly before the data file itself. The file will tne look something like this:
: : : :
: : : : your executable
: : : : size of file 1 (option: + target directory)
: : : : file 1
: : : : size of file 2 (option: + target directory)
: : : : file 2
: : : : ...
: : : : size of your executable
: : : :
: : : : Your extraction program just needs to read its own size to get the start of the data. Then it needs to read the size of the first data file (and if necessary the target directory), and extract the data file itself. The last step can be repeated for each data file.
: : : : This will require some careful programming using BlockRead()s and BlockWrite()s.
: : : :
: : : : The best way to add the data files to your program is to write another program, which opens the executable for writing and writes each data file into it. Finally it writes the original executable size. This shouldn't be too difficult. Again the biggest problem here is that you need to be very careful not to corrupt the sizes and files themselves.
: : : :
: : : I understood what you mean but I find it a little bit difficult.Is there a source code of some similar program ? May be if I see some source I won't have any problems to do this program. Thank you very much.
: : :
: : I don't know if anybody else has created such a code, but here's what I created.
: :
: : unit intdataf;
: :
: : interface
: :
: : uses
: : SysUtils;
: :
: : type
: : TDOSFilename = string[12];
: :
: : TInternalDataFile = class(TObject)
: : private
: : FSize: integer;
: : FBufferSize: integer;
: : FFilename: TDOSFileName;
: : FPath: string;
: : protected
: : public
: : property Size: integer read FSize;
: : property Filename: TDOSFileName read FFilename;
: : property Path: string read FPath write FPath;
: : property BufferSize: integer read FBufferSize write FBufferSize;
: : constructor Create;
: : procedure Extract(var selffile: file);
: : end;
: :
: : procedure OpenSelf(var selffile: file);
: : procedure CloseSelf(var selffile: file);
: :
: : {
: : Implemented data format per data file:
: : 0..3 Size of Data file = FSize
: : 4..15 Filename of Data file = FFilename
: : 16..FSize+15 Data file
: : Implemented Data format for entire file:
: : 0..ExeSize-1 Normal executable as created by compiler
: : ExeSize..#000# First Data file
: : #000#+1..#001# Second Data file
: : etc.
: : Total FileSize-4..Total FileSize-1 Size of normal executable
: : }
: :
: : { =========================
: : Example:
: : =========================
: :
: : var
: : exefile: file;
: : DataFile: TInternalDataFile;
: : begin
: : DataFile := TInternalDataFile.Create;
: : DataFile.Buffer := 2048; // set buffer to 2 kB
: : DataFile.Path := 'c:\'; // create all files in root of C:-drive
: : OpenSelf(exefile); // open the execuable and search for the start of the data files
: : DataFile.Extract(exefile); // extract first data file
: : DataFile.Extract(exefile); // extract second data file
: : // repeat as often as you need
: : CloseSelf(exefile); // clean-up the memory
: : DataFile.Free;
: : end;
: : }
: :
: : implementation
: :
: : procedure OpenSelf(var selffile: file);
: : var
: : i: integer;
: : begin
: : AssignFile(selffile, ParamStr(0)); // Get filename from CmdLine
: : Reset(selffile, 1);
: : Seek(selffile, FileSize(selffile)-4); // Seek executable size
: : BlockRead(selffile, i, SizeOf(i));
: : Seek(selffile, i); // Seek begin of data files
: : end;
: :
: : procedure CloseSelf(var selffile: file);
: : begin
: : CloseFile(selffile);
: : end;
: :
: : { TInternalDataFile }
: :
: : constructor TInternalDataFile.Create;
: : begin
: : inherited Create;
: : FBufferSize := 1024; // default buffer: 1 kB
: : end;
: :
: : procedure TInternalDataFile.Extract(var selffile: file);
: : var
: : Buffer: Pointer;
: : extfile: file;
: : i: integer;
: : begin
: : GetMem(Buffer, FBufferSize); // Build buffer
: : try
: : BlockRead(selffile, FSize, SizeOf(FSize)); // Get size of data file
: : BlockRead(selffile, FFilename, SizeOf(FFilename)); // Get filename of data file
: : AssignFile(extfile, IncludeTrailingBackslash(FPath)+FFilename);
: : Rewrite(extfile, 1);
: : // create new data file as pecified by FPath and FFilename
: : for i := 0 to FSize div FBufferSize do begin // copy file out of exe using
: : BlockRead(selffile, Buffer^, FBufferSize); // the buffer for speed
: : BlockWrite(extfile, Buffer^, FBufferSize);
: : end;
: : BlockRead(selffile, Buffer^, FSize mod FBufferSize); // Copy remainder of
: : BlockWrite(extfile, Buffer^, FSize mod FBufferSize); // data file
: : finally
: : CloseFile(extfile); // Close file
: : FreeMem(Buffer, FBufferSize); // and free buffer
: : end;
: : end;
: :
: : end.
: :
: : I've included a small example to get you started. Creating a program to add the files to the executable can be coded along similar lines.
: :
: zibadian, you are great ! Thank you very much. I will try the program tomorrow and if it works I will tell you.
:
I started to write the program that adds the files to the executable but there is a problem. My program added the files to the end of the executable and now the executable is not executable. It is damaged.