home *** CD-ROM | disk | FTP | other *** search
- {
- EXEMOD.PAS - Modify global variables in EXE file
-
- Kevin Dean
- 16 Kellythorne Drive
- DOn Mills, Ontario
- Canada M3A 2L4
-
- March 27, 1990
-
- Modifies global variables (typed constants) in initialized data segment of EXE
- files. Cannot modify global variables that are declared but not initialized
- (i.e. global variables that are not typed constants) as these lie in the BSS
- segment of the program and are not in fact in the EXE image file itself.
-
- Copyright (c) 1990 by Kevin Dean
-
- For Turbo Pascal versions 5.0 and above. This code is public domain.
- }
-
-
- {$B-,O+,R-,I-}
- unit EXEMod;
-
-
- interface
-
-
- uses
- DOS;
-
-
- type
- EXEHeader =
- record
- ID : word; { EXE file id }
- ByteMod : word; { Load module image size mod 512 }
- Pages : word; { File size (including header) div 512 }
- RelocItems : word; { Number of relocation table items }
- Size : word; { Header size in 16-byte paragraphs }
- MinParagraphs : word; { Minimum number of paragraphs above program }
- MaxParagraphs : word; { Maximum number of paragraphs above program }
- StackSeg : word; { Displacement of stack segment }
- SPReg : word; { Initial SP register value }
- CheckSum : integer; { Word checksum - negative sum (not used) }
- IPReg : word; { Initial IP register value }
- CodeSeg : word; { Displacement of code segment }
- FirstReloc : word; { First relocation item }
- OvlN : word { Overlay number }
- end;
-
- const
- EXEHSize =
- sizeof(EXEHeader);
-
- EXEID = { EXE file signature }
- $5A4D;
-
-
- function EXEModify(ProgName : PathStr; KeepDT : boolean; var Data; N : word) : integer;
-
-
- implementation
-
-
- {***}
- {
- Name EXEModify
-
- Function Modifies static data in EXE files.
-
- Declaration EXEModify(ProgName : PathStr; KeepDT : boolean; var Data;
- N : word)
-
- Result type integer
-
- Remarks EXEModify modifies global variables (typed constants) in the
- initialized data segment of the current EXE file. In DOS
- versions 3.0 and up, EXEModify takes the program name from
- ParamStr(0). In DOS versions below 3.0, EXEModify searches the
- DOS path for the program passed in ProgName.
-
- If KeepDT is true, then the original file date/time stamp is
- preserved.
-
- EXEModify cannot modify global variables that are declared but
- not initialized (i.e. global variables that are not typed
- constants) as these lie in the BSS segment of the program and
- are not in fact in the EXE image file itself.
-
- Return value EXEModify returns 1 if successful (data modified in EXE file),
- 0 if EXE file found but data item is not in the EXE file, and
- -1 in case of file error (e.g. file not found). If the return
- value is -1, check for a file error with IOResult.
- }
- function EXEModify(ProgName : PathStr; KeepDT : boolean; var Data; N : word) : integer;
-
- var
- _ProgName : PathStr; { Program name }
- RetCode : integer; { Function return code }
- OldFileMode : byte; { Old file open mode }
- ProgFile : file; { Program file handle }
- EXE : EXEHeader; { EXE file header }
- NumRW : word; { Number of bytes read or written }
- FileLen : longint; { Program file length }
- DTStamp : longint; { Program date/time stamp }
- SeekLen : longint; { Seek length into program file }
-
- begin
- if Lo(DOSVersion) < 3 then
- { Search path for program }
- begin
- _ProgName := FSearch(ProgName, GetEnv('PATH'));
- if _ProgName <> '' then
- _ProgName := FExpand(_ProgName);
- end
- else
- { Program name is 0th parameter in DOS versions 3.0 and up }
- _ProgName := ParamStr(0);
-
- { Assume error }
- RetCode := -1;
-
- if _ProgName <> '' then
- begin
- { Set file mode to allow reading and writing }
- OldFileMode := FileMode;
- FileMode := 2;
-
- Assign(ProgFile, _ProgName);
- Reset(ProgFile, 1);
-
- FileMode := OldFileMode;
-
- if InOutRes = 0 then
- begin
- BlockRead(ProgFile, EXE, EXEHSize, NumRW);
-
- if (NumRW <> EXEHSize) or (EXE.ID <> EXEID) then
- { File does not have valid EXE file header so say file not found }
- InOutRes := 2
- else
- begin
- { Cannot write beyond end of file }
- FileLen := FileSize(ProgFile);
-
- if KeepDT then
- { Save date/time stamp }
- GetFTime(ProgFile, DTStamp);
-
- RetCode := 0;
-
- SeekLen := LongInt(Seg(Data) - (PrefixSeg + 16) + EXE.Size) shl 4 + LongInt(Ofs(Data));
-
- if SeekLen + N <= FileLen then
- begin
- Seek(ProgFile, SeekLen);
- if InOutRes = 0 then
- begin
- BlockWrite(ProgFile, Data, N, NumRW);
- if (InOutRes = 0) and (NumRW = N) then
- { Seek and write was successful }
- RetCode := 1
- end
- end;
-
- if KeepDT then
- { Restore date/time stamp }
- SetFTime(ProgFile, DTStamp)
- end;
-
- Close(ProgFile)
- end
- end
- else
- { File not found }
- InOutRes := 2;
-
- EXEModify := RetCode
- end;
-
-
- end.