Skip to content

Commit

Permalink
Cleanup unit descriptions.
Browse files Browse the repository at this point in the history
Rename CompResUpdate to CompExeUpdate and mmove UpdateSetupPEHeaderFields into it.
Fix old names use in dproj.
  • Loading branch information
martijnlaan committed Aug 12, 2020
1 parent 3dc84f2 commit faf4df6
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 148 deletions.
156 changes: 131 additions & 25 deletions Projects/CompResUpdate.pas → Projects/CompExeUpdate.pas
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
unit CompResUpdate;
unit CompExeUpdate;

{
Inno Setup
Copyright (C) 1997-2020 Jordan Russell
Portions by Martijn Laan
For conditions of distribution and use, see LICENSE.TXT.
Resource update functions used by the compiler only
PE header and resource update functions used by the compiler only
}

interface
Expand All @@ -16,6 +16,8 @@ interface

{$I VERSION.INC}

procedure UpdateSetupPEHeaderFields(const F: TCustomFile;
const IsVistaCompatible, IsTSAware, IsDEPCompatible, IsASLRCompatible: Boolean);
procedure UpdateIcons(const FileName, IcoFileName: String);
procedure UpdateVersionInfo(const F: TCustomFile;
const NewBinaryFileVersion, NewBinaryProductVersion: TFileVersionNumbers;
Expand All @@ -29,14 +31,118 @@ implementation
uses
ResUpdate{$IFDEF UNICODE}, Math{$ENDIF}, Int64Em;

procedure Error(const Msg: String);
procedure UpdateSetupPEHeaderFields(const F: TCustomFile;
const IsVistaCompatible, IsTSAware, IsDEPCompatible, IsASLRCompatible: Boolean);

function SeekToPEHeader(const F: TCustomFile): Boolean;
var
DosHeader: packed record
Sig: array[0..1] of AnsiChar;
Other: array[0..57] of Byte;
PEHeaderOffset: LongWord;
end;
Sig: DWORD;
begin
Result := False;
F.Seek(0);
if F.Read(DosHeader, SizeOf(DosHeader)) = SizeOf(DosHeader) then begin
if (DosHeader.Sig[0] = 'M') and (DosHeader.Sig[1] = 'Z') and
(DosHeader.PEHeaderOffset <> 0) then begin
F.Seek(DosHeader.PEHeaderOffset);
if F.Read(Sig, SizeOf(Sig)) = SizeOf(Sig) then
if Sig = IMAGE_NT_SIGNATURE then
Result := True;
end;
end;
end;

const
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = $0040;
IMAGE_DLLCHARACTERISTICS_NX_COMPAT = $0100;
IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = $8000;
OffsetOfOperatingSystemVersion = $28;
OffsetOfImageVersion = $2C;
OffsetOfSubsystemVersion = $30;
OffsetOfDllCharacteristics = $46;
var
Header: TImageFileHeader;
Ofs: Cardinal;
OptMagic, DllChars, OrigDllChars: Word;
VersionRecord: packed record
Major, Minor: Word;
end;
begin
if SeekToPEHeader(F) then begin
if (F.Read(Header, SizeOf(Header)) = SizeOf(Header)) and
(Header.SizeOfOptionalHeader = 224) then begin
Ofs := F.Position.Lo;
if (F.Read(OptMagic, SizeOf(OptMagic)) = SizeOf(OptMagic)) and
(OptMagic = IMAGE_NT_OPTIONAL_HDR32_MAGIC) then begin
if IsVistaCompatible then begin
{ Update OS/Subsystem version }
VersionRecord.Major := 6;
VersionRecord.Minor := 0;
F.Seek(Ofs + OffsetOfOperatingSystemVersion);
F.WriteBuffer(VersionRecord, SizeOf(VersionRecord));
F.Seek(Ofs + OffsetOfSubsystemVersion);
F.WriteBuffer(VersionRecord, SizeOf(VersionRecord));
end;

{ Update MajorImageVersion and MinorImageVersion to 6.0.
Works around apparent bug in Vista (still present in Vista SP1;
not reproducible on Server 2008): When UAC is turned off,
launching an uninstaller (as admin) from ARP and answering No at the
ConfirmUninstall message box causes a "This program might not have
uninstalled correctly" dialog to be displayed, even if the EXE
has a proper "Vista-aware" manifest. I discovered that if the EXE's
image version is set to 6.0, like the EXEs that ship with Vista
(notepad.exe), the dialog does not appear. (This is reproducible
with notepad.exe too if its image version is changed to anything
other than 6.0 exactly.) }
VersionRecord.Major := 6;
VersionRecord.Minor := 0;
F.Seek(Ofs + OffsetOfImageVersion);
F.WriteBuffer(VersionRecord, SizeOf(VersionRecord));

{ Update DllCharacteristics }
F.Seek(Ofs + OffsetOfDllCharacteristics);
if F.Read(DllChars, SizeOf(DllChars)) = SizeOf(DllChars) then begin
OrigDllChars := DllChars;
if IsTSAware then
DllChars := DllChars or IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
else
DllChars := DllChars and not IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE;
if IsDEPCompatible then
DllChars := DllChars or IMAGE_DLLCHARACTERISTICS_NX_COMPAT
else
DllChars := DllChars and not IMAGE_DLLCHARACTERISTICS_NX_COMPAT;
{ Note: because we stripped relocations from Setup(Ldr).e32 during
compilation IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE won't actually
enable ASLR, but allow setting it anyway to make checkers happy. }
if IsASLRCompatible then
DllChars := DllChars or IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
else
DllChars := DllChars and not IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE;
if DllChars <> OrigDllChars then begin
F.Seek(Ofs + OffsetOfDllCharacteristics);
F.WriteBuffer(DllChars, SizeOf(DllChars));
end;
Exit;
end;
end;
end;
end;
raise Exception.Create('UpdateSetupPEHeaderFields failed');
end;

procedure ResUpdateError(const Msg: String);
begin
raise Exception.Create('Resource update error: ' + Msg);
end;

procedure ErrorWithLastError(const Msg: String);
procedure ResUpdateErrorWithLastError(const Msg: String);
begin
Error(Msg + ' (' + IntToStr(GetLastError) + ')');
ResUpdateError(Msg + ' (' + IntToStr(GetLastError) + ')');
end;

procedure UpdateVersionInfo(const F: TCustomFile;
Expand Down Expand Up @@ -139,7 +245,7 @@ procedure UpdateVersionInfo(const F: TCustomFile;
ValueLen: Cardinal;
begin
if not QueryValue(P, Path, Pointer(Value), ValueLen) then
Error('Unexpected version resource format (1)');
ResUpdateError('Unexpected version resource format (1)');
{$IFDEF UNICODE}
Move(Pointer(NewValue)^, Value^, (Min(Length(NewValue), lstrlenW(Value)))*SizeOf(Char));
{$ELSE}
Expand All @@ -156,9 +262,9 @@ procedure UpdateVersionInfo(const F: TCustomFile;
ValueLen: Cardinal;
begin
if not QueryValue(P, Path, Pointer(FixedFileInfo), ValueLen) then
Error('Unexpected version resource format (2)');
ResUpdateError('Unexpected version resource format (2)');
if FixedFileInfo.dwSignature <> $FEEF04BD then
Error('Unexpected version resource format (3)');
ResUpdateError('Unexpected version resource format (3)');
if SetFileVersion then begin
FixedFileInfo.dwFileVersionLS := NewFileVersion.LS;
FixedFileInfo.dwFileVersionMS := NewFileVersion.MS;
Expand Down Expand Up @@ -287,7 +393,7 @@ procedure UpdateIcons(const FileName, IcoFileName: String);
NewGroupIconDirSize: LongInt;
begin
if Win32Platform <> VER_PLATFORM_WIN32_NT then
Error('Only supported on Windows NT and above');
ResUpdateError('Only supported on Windows NT and above');

Ico := nil;

Expand All @@ -297,7 +403,7 @@ procedure UpdateIcons(const FileName, IcoFileName: String);
try
N := F.CappedSize;
if Cardinal(N) > Cardinal($100000) then { sanity check }
Error('Icon file is too large');
ResUpdateError('Icon file is too large');
GetMem(Ico, N);
F.ReadBuffer(Ico^, N);
finally
Expand All @@ -306,40 +412,40 @@ procedure UpdateIcons(const FileName, IcoFileName: String);

{ Ensure the icon is valid }
if not IsValidIcon(Ico, N) then
Error('Icon file is invalid');
ResUpdateError('Icon file is invalid');

{ Update the resources }
H := BeginUpdateResource(PChar(FileName), False);
if H = 0 then
ErrorWithLastError('BeginUpdateResource failed (1)');
ResUpdateErrorWithLastError('BeginUpdateResource failed (1)');
try
M := LoadLibraryEx(PChar(FileName), 0, LOAD_LIBRARY_AS_DATAFILE);
if M = 0 then
ErrorWithLastError('LoadLibraryEx failed (1)');
ResUpdateErrorWithLastError('LoadLibraryEx failed (1)');
try
{ Load the 'MAINICON' group icon resource }
R := FindResource(M, 'MAINICON', RT_GROUP_ICON);
if R = 0 then
ErrorWithLastError('FindResource failed (1)');
ResUpdateErrorWithLastError('FindResource failed (1)');
Res := LoadResource(M, R);
if Res = 0 then
ErrorWithLastError('LoadResource failed (1)');
ResUpdateErrorWithLastError('LoadResource failed (1)');
GroupIconDir := LockResource(Res);
if GroupIconDir = nil then
ErrorWithLastError('LockResource failed (1)');
ResUpdateErrorWithLastError('LockResource failed (1)');

{ Delete 'MAINICON' }
if not GetResourceLanguage(M, RT_GROUP_ICON, 'MAINICON', wLanguage) then
Error('GetResourceLanguage failed (1)');
ResUpdateError('GetResourceLanguage failed (1)');
if not UpdateResource(H, RT_GROUP_ICON, 'MAINICON', wLanguage, nil, 0) then
ErrorWithLastError('UpdateResource failed (1)');
ResUpdateErrorWithLastError('UpdateResource failed (1)');

{ Delete the RT_ICON icon resources that belonged to 'MAINICON' }
for I := 0 to GroupIconDir.ItemCount-1 do begin
if not GetResourceLanguage(M, RT_ICON, MakeIntResource(GroupIconDir.Items[I].Id), wLanguage) then
Error('GetResourceLanguage failed (2)');
ResUpdateError('GetResourceLanguage failed (2)');
if not UpdateResource(H, RT_ICON, MakeIntResource(GroupIconDir.Items[I].Id), wLanguage, nil, 0) then
ErrorWithLastError('UpdateResource failed (2)');
ResUpdateErrorWithLastError('UpdateResource failed (2)');
end;

{ Build the new group icon resource }
Expand All @@ -358,11 +464,11 @@ procedure UpdateIcons(const FileName, IcoFileName: String);
{ Update 'MAINICON' }
for I := 0 to NewGroupIconDir.ItemCount-1 do
if not UpdateResource(H, RT_ICON, MakeIntResource(NewGroupIconDir.Items[I].Id), 1033, Pointer(DWORD(Ico) + Ico.Items[I].Offset), Ico.Items[I].Header.ImageSize) then
ErrorWithLastError('UpdateResource failed (3)');
ResUpdateErrorWithLastError('UpdateResource failed (3)');

{ Update the icons }
if not UpdateResource(H, RT_GROUP_ICON, 'MAINICON', 1033, NewGroupIconDir, NewGroupIconDirSize) then
ErrorWithLastError('UpdateResource failed (4)');
ResUpdateErrorWithLastError('UpdateResource failed (4)');
finally
FreeMem(NewGroupIconDir);
end;
Expand All @@ -374,7 +480,7 @@ procedure UpdateIcons(const FileName, IcoFileName: String);
raise;
end;
if not EndUpdateResource(H, False) then
ErrorWithLastError('EndUpdateResource failed');
ResUpdateErrorWithLastError('EndUpdateResource failed');
finally
FreeMem(Ico);
end;
Expand All @@ -397,9 +503,9 @@ procedure RemoveManifestDllHijackProtection(const F: TCustomFile; const TestBloc
{ Locate and update the block with file elements }
P := Pos(BlockStartText, S);
if P = 0 then
Error('Block not found');
ResUpdateError('Block not found');
if Copy(S, P+BlockLength, 11) <> '</assembly>' then
Error('Block too short');
ResUpdateError('Block too short');

if TestBlockOnly then
Exit;
Expand Down
2 changes: 1 addition & 1 deletion Projects/CompFileAssoc.pas
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Portions by Martijn Laan
For conditions of distribution and use, see LICENSE.TXT.
Functions for registering/unregistering the .iss file association
Compiler IDE's functions for registering/unregistering the .iss file association
}

interface
Expand Down
4 changes: 2 additions & 2 deletions Projects/CompOptions.pas
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

{
Inno Setup
Copyright (C) 1997-2018 Jordan Russell
Copyright (C) 1997-2020 Jordan Russell
Portions by Martijn Laan
For conditions of distribution and use, see LICENSE.TXT.
Compiler Options form
Compiler IDE Options form
}

interface
Expand Down
2 changes: 1 addition & 1 deletion Projects/CompSignTools.pas
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Portions by Martijn Laan
For conditions of distribution and use, see LICENSE.TXT.
Compiler SignTools form
Compiler IDE SignTools form
}

interface
Expand Down
6 changes: 2 additions & 4 deletions Projects/CompStartup.pas
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@

{
Inno Setup
Copyright (C) 1997-2004 Jordan Russell
Copyright (C) 1997-2020 Jordan Russell
Portions by Martijn Laan
For conditions of distribution and use, see LICENSE.TXT.
Compiler Startup form
$jrsoftware: issrc/Projects/CompStartup.pas,v 1.11 2004/07/22 19:49:39 jr Exp $
Compiler IDE Startup form
}

interface
Expand Down
4 changes: 2 additions & 2 deletions Projects/CompWizard.pas
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

{
Inno Setup
Copyright (C) 1997-2019 Jordan Russell
Copyright (C) 1997-2020 Jordan Russell
Portions by Martijn Laan
For conditions of distribution and use, see LICENSE.TXT.
Compiler Script Wizard form
Compiler IDE Script Wizard form
}

interface
Expand Down
6 changes: 2 additions & 4 deletions Projects/CompWizardFile.pas
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@

{
Inno Setup
Copyright (C) 1997-2010 Jordan Russell
Copyright (C) 1997-2020 Jordan Russell
Portions by Martijn Laan
For conditions of distribution and use, see LICENSE.TXT.
Compiler Script Wizard File form
$jrsoftware: issrc/Projects/CompWizardFile.pas,v 1.11 2010/03/06 22:33:02 jr Exp $
Compiler IDE Script Wizard File form
}

interface
Expand Down
4 changes: 2 additions & 2 deletions Projects/Compil32.dproj
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@
<Form>WizardFileForm</Form>
</DCCReference>
<DCCReference Include="CompFileAssoc.pas"/>
<DCCReference Include="..\Components\TmSchemaISX.pas"/>
<DCCReference Include="..\Components\UxThemeISX.pas"/>
<DCCReference Include="..\Components\TmSchema.pas"/>
<DCCReference Include="..\Components\UxTheme.pas"/>
<DCCReference Include="DebugStruct.pas"/>
<DCCReference Include="BrowseFunc.pas"/>
<DCCReference Include="CompSignTools.pas">
Expand Down
Loading

0 comments on commit faf4df6

Please sign in to comment.