Prechádzať zdrojové kódy

Cleanup by moving the 'main' fields into a new struct and add an extra CRC check.

Cleanup todo: at least cleanup FileExtractor's and HandleInitPassword's direct use of Setup(Main)Header + add constants for the -1/-2/-3 nonce xors.
Martijn Laan 1 mesiac pred
rodič
commit
80cf6b585d

+ 22 - 20
Projects/SetupLdr.dpr

@@ -79,6 +79,7 @@ var
   InitLang, InitPassword: String;
   ActiveLanguage: Integer = -1;
   PendingNewLanguage: Integer = -1;
+  SetupMainHeader: TSetupMainHeader;
   SetupHeader: TSetupHeader;
   LanguageEntries: PLanguageEntryArray;
   LanguageEntryCount: Integer;
@@ -408,29 +409,30 @@ begin
       SourceF.ReadBuffer(TestID, SizeOf(TestID));
       if TestID <> SetupID then
         SetupCorruptError;
-      try
-        var CryptKey: TSetupEncryptionKey;
-        SourceF.Read(SetupHeader.EncryptionUse, SizeOf(SetupHeader.EncryptionUse));
-        if SetupHeader.EncryptionUse = euFull then begin
-          SourceF.Read(SetupHeader.EncryptionKDFSalt, SizeOf(SetupHeader.EncryptionKDFSalt));
-          SourceF.Read(SetupHeader.EncryptionKDFIterations, SizeOf(SetupHeader.EncryptionKDFIterations));
-          SourceF.Read(SetupHeader.EncryptionBaseNonce, SizeOf(SetupHeader.EncryptionBaseNonce));
-          SourceF.Read(SetupHeader.PasswordTest, SizeOf(SetupHeader.PasswordTest));
-          SourceF.Read(SetupHeader.CompressMethod, SizeOf(SetupHeader.CompressMethod));
-          var PasswordOk: Boolean;
-          if InitPassword <> '' then begin
-            GenerateEncryptionKey(InitPassword, SetupHeader.EncryptionKDFSalt, SetupHeader.EncryptionKDFIterations, CryptKey);
-            PasswordOk := TestPassword(CryptKey, SetupHeader.EncryptionBaseNonce, SetupHeader.PasswordTest);
-          end else
-            PasswordOk := False;
-          if not PasswordOk then
-            raise Exception.Create(SIncorrectPassword);
-        end;
 
+      var SetupMainHeaderCRC: Longint;
+      SourceF.Read(SetupMainHeaderCRC, SizeOf(SetupMainHeaderCRC));
+      SourceF.Read(SetupMainHeader, SizeOf(SetupMainHeader));
+      if SetupMainHeaderCRC <> GetCRC32(SetupMainHeader, SizeOf(SetupMainHeader)) then
+         SetupCorruptError;
+
+      var CryptKey: TSetupEncryptionKey;
+      if SetupMainHeader.EncryptionUse = euFull then begin
+        var PasswordOk: Boolean;
+        if InitPassword <> '' then begin
+          GenerateEncryptionKey(InitPassword, SetupMainHeader.EncryptionKDFSalt, SetupMainHeader.EncryptionKDFIterations, CryptKey);
+          PasswordOk := TestPassword(CryptKey, SetupMainHeader.EncryptionBaseNonce, SetupMainHeader.PasswordTest);
+        end else
+          PasswordOk := False;
+        if not PasswordOk then
+          raise Exception.Create(SIncorrectPassword);
+      end;
+
+      try
         Reader := TCompressedBlockReader.Create(SourceF, TLZMA1SmallDecompressor);
         try
-          if SetupHeader.EncryptionUse = euFull then
-            Reader.InitDecryption(CryptKey, SetupHeader.EncryptionBaseNonce, -2);
+          if SetupMainHeader.EncryptionUse = euFull then
+            Reader.InitDecryption(CryptKey, SetupMainHeader.EncryptionBaseNonce, -2);
 
           SECompressedBlockRead(Reader, SetupHeader, SizeOf(SetupHeader),
             SetupHeaderStrings, SetupHeaderAnsiStrings);

+ 29 - 31
Projects/Src/Compiler.SetupCompiler.pas

@@ -127,6 +127,7 @@ type
     TouchTimeOption: (ttCurrent, ttNone, ttExplicit);
     TouchTimeHour, TouchTimeMinute, TouchTimeSecond: Integer;
 
+    SetupMainHeader: TSetupMainHeader;
     SetupHeader: TSetupHeader;
 
     SetupDirectiveLines: array[TSetupSectionDirective] of Integer;
@@ -631,7 +632,7 @@ end;
 
 function TSetupCompiler.GetEncryptionBaseNonce: TSetupEncryptionNonce;
 begin
-  Result := SetupHeader.EncryptionBaseNonce;
+  Result := SetupMainHeader.EncryptionBaseNonce;
 end;
 
 function TSetupCompiler.GetExeFilename: String;
@@ -2837,20 +2838,20 @@ begin
       end;
     ssEncryption: begin
         if CompareText(Value, 'full') = 0 then
-          SetupHeader.EncryptionUse := euFull
+          SetupMainHeader.EncryptionUse := euFull
         else if StrToBool(Value) then
-          SetupHeader.EncryptionUse := euFiles
+          SetupMainHeader.EncryptionUse := euFiles
         else
-          SetupHeader.EncryptionUse := euNone;
+          SetupMainHeader.EncryptionUse := euNone;
       end;
     ssEncryptionKeyDerivation: begin
         if Value = 'pbkdf2' then
-          SetupHeader.EncryptionKDFIterations := 200000
+          SetupMainHeader.EncryptionKDFIterations := 200000
         else if Copy(Value, 1, 7) = 'pbkdf2/' then begin
           I := StrToIntDef(Copy(Value, 8, Maxint), -1);
           if I < 1 then
             Invalid;
-          SetupHeader.EncryptionKDFIterations := I;
+          SetupMainHeader.EncryptionKDFIterations := I;
         end else
           Invalid;
       end;
@@ -5010,7 +5011,7 @@ type
         if NewFileLocationEntry = nil then begin
           NewFileLocationEntry := AllocMem(SizeOf(TSetupFileLocationEntry));
           NewFileLocationEntryExtraInfo := AllocMem(SizeOf(TFileLocationEntryExtraInfo));
-          SetupHeader.CompressMethod := CompressMethod;
+          SetupMainHeader.CompressMethod := CompressMethod;
           FileLocationEntries.Add(NewFileLocationEntry);
           FileLocationEntryExtraInfos.Add(NewFileLocationEntryExtraInfo);
           FileLocationEntryFilenames.Add(SourceFile);
@@ -5018,9 +5019,9 @@ type
           if NewFileEntry^.FileType = ftUninstExe then
             Include(NewFileLocationEntryExtraInfo^.Flags, floIsUninstExe);
           Inc6464(TotalBytesToCompress, FileListRec.Size);
-          if SetupHeader.CompressMethod <> cmStored then
+          if SetupMainHeader.CompressMethod <> cmStored then
             Include(NewFileLocationEntry^.Flags, floChunkCompressed);
-          if SetupHeader.EncryptionUse <> euNone then
+          if SetupMainHeader.EncryptionUse <> euNone then
             Include(NewFileLocationEntry^.Flags, floChunkEncrypted);
           if SolidBreak and UseSolidCompression then begin
             Include(NewFileLocationEntryExtraInfo^.Flags, floSolidBreak);
@@ -6891,14 +6892,10 @@ var
     const StartPosition = F.Position;
 
     F.WriteBuffer(SetupID, SizeOf(SetupID));
-    F.WriteBuffer(SetupHeader.EncryptionUse, SizeOf(SetupHeader.EncryptionUse));
-    if SetupHeader.EncryptionUse = euFull then begin
-      F.WriteBuffer(SetupHeader.EncryptionKDFSalt, SizeOf(SetupHeader.EncryptionKDFSalt));
-      F.WriteBuffer(SetupHeader.EncryptionKDFIterations, SizeOf(SetupHeader.EncryptionKDFIterations));
-      F.WriteBuffer(SetupHeader.EncryptionBaseNonce, SizeOf(SetupHeader.EncryptionBaseNonce));
-      F.WriteBuffer(SetupHeader.PasswordTest, SizeOf(SetupHeader.PasswordTest));
-      F.WriteBuffer(SetupHeader.CompressMethod, SizeOf(SetupHeader.CompressMethod));
-    end;
+    const SetupMainHeaderCRC = GetCRC32(SetupMainHeader, SizeOf(SetupMainHeader));
+    F.WriteBuffer(SetupMainHeaderCRC, SizeOf(SetupMainHeaderCRC));
+    F.WriteBuffer(SetupMainHeader, SizeOf(SetupMainHeader));
+
     SetupHeader.NumLanguageEntries := LanguageEntries.Count;
     SetupHeader.NumCustomMessageEntries := CustomMessageEntries.Count;
     SetupHeader.NumPermissionEntries := PermissionEntries.Count;
@@ -6924,8 +6921,8 @@ var
     W := TCompressedBlockWriter.Create(F, TLZMACompressor, InternalCompressLevel,
       InternalCompressProps);
     try
-      if SetupHeader.EncryptionUse = euFull then
-        W.InitEncryption(CryptKey, SetupHeader.EncryptionBaseNonce, -2);
+      if SetupMainHeader.EncryptionUse = euFull then
+        W.InitEncryption(CryptKey, SetupMainHeader.EncryptionBaseNonce, -2);
 
       SECompressedBlockWrite(W, SetupHeader, SizeOf(SetupHeader),
         SetupHeaderStrings, SetupHeaderAnsiStrings);
@@ -6985,7 +6982,7 @@ var
       W.Write(WizardSmallImages.Count, SizeOf(Integer));
       for J := 0 to WizardSmallImages.Count-1 do
         WriteStream(WizardSmallImages[J], W);
-      if SetupHeader.CompressMethod in [cmZip, cmBzip] then
+      if SetupMainHeader.CompressMethod in [cmZip, cmBzip] then
         WriteStream(DecompressorDLL, W);
       if SetupHeader.SevenZipLibraryName <> '' then
         WriteStream(SevenZipDLL, W);
@@ -7003,8 +7000,8 @@ var
       { ^ When disk spanning is enabled, the Setup Compiler requires that
         FileLocationEntries be a fixed size, so don't compress them }
     try
-      if SetupHeader.EncryptionUse = euFull then
-        W.InitEncryption(CryptKey, SetupHeader.EncryptionBaseNonce, -3);
+      if SetupMainHeader.EncryptionUse = euFull then
+        W.InitEncryption(CryptKey, SetupMainHeader.EncryptionBaseNonce, -3);
       for J := 0 to FileLocationEntries.Count-1 do
         W.Write(FileLocationEntries[J]^, SizeOf(TSetupFileLocationEntry));
       W.Finish;
@@ -7083,7 +7080,7 @@ var
       if not UseCompression then
         Result := TStoredCompressor
       else begin
-        case SetupHeader.CompressMethod of
+        case SetupMainHeader.CompressMethod of
           cmStored: begin
               Result := TStoredCompressor;
             end;
@@ -7147,7 +7144,7 @@ var
     HdrChecksum, ErrorCode: DWORD;
     ISSigAvailableKeys: TArrayOfECDSAKey;
   begin
-    if (SetupHeader.CompressMethod in [cmLZMA, cmLZMA2]) and
+    if (SetupMainHeader.CompressMethod in [cmLZMA, cmLZMA2]) and
        (CompressProps.WorkerProcessFilename <> '') then
       AddStatus(Format('   Using separate process for LZMA compression (%s)',
         [PathExtractName(CompressProps.WorkerProcessFilename)]));
@@ -7709,6 +7706,7 @@ begin
   SevenZipDLL := nil;
 
   try
+    FillChar(SetupMainHeader, SizeOf(SetupMainHeader), 0);
     Finalize(SetupHeader);
     FillChar(SetupHeader, SizeOf(SetupHeader), 0);
     InitDebugInfo;
@@ -7777,7 +7775,7 @@ begin
     NotRecognizedMessagesWarning := True;
     UsedUserAreasWarning := True;
     SetupHeader.WizardStyle := wsClassic;
-    SetupHeader.EncryptionKDFIterations := 220000;
+    SetupMainHeader.EncryptionKDFIterations := 220000;
 
     { Read [Setup] section }
     EnumIniSection(EnumSetupProc, 'Setup', 0, True, True, '', False, False);
@@ -7924,7 +7922,7 @@ begin
       else
         VersionInfoProductTextVersion := VersionInfoProductVersionOriginalValue;
     end;
-    if (SetupHeader.EncryptionUse <> euNone) and (Password = '') then begin
+    if (SetupMainHeader.EncryptionUse <> euNone) and (Password = '') then begin
       LineNumber := SetupDirectiveLines[ssEncryption];
       AbortCompileFmt(SCompilerEntryMissing2, ['Setup', 'Password']);
     end;
@@ -7995,10 +7993,10 @@ begin
     end;
 
     if Password <> '' then begin
-      GenerateEncryptionKDFSalt(SetupHeader.EncryptionKDFSalt);
-      GenerateEncryptionKey(Password,  SetupHeader.EncryptionKDFSalt, SetupHeader.EncryptionKDFIterations, CryptKey);
-      GenerateEncryptionBaseNonce(SetupHeader.EncryptionBaseNonce);
-      GeneratePasswordTest(CryptKey, SetupHeader.EncryptionBaseNonce, SetupHeader.PasswordTest);
+      GenerateEncryptionKDFSalt(SetupMainHeader.EncryptionKDFSalt);
+      GenerateEncryptionKey(Password,  SetupMainHeader.EncryptionKDFSalt, SetupMainHeader.EncryptionKDFIterations, CryptKey);
+      GenerateEncryptionBaseNonce(SetupMainHeader.EncryptionBaseNonce);
+      GeneratePasswordTest(CryptKey, SetupMainHeader.EncryptionBaseNonce, SetupMainHeader.PasswordTest);
       Include(SetupHeader.Options, shPassword);
     end;
 
@@ -8225,7 +8223,7 @@ begin
 
     { Read decompressor DLL. Must be done after [Files] is parsed, since
       SetupHeader.CompressMethod isn't set until then }
-    case SetupHeader.CompressMethod of
+    case SetupMainHeader.CompressMethod of
       cmZip: begin
           AddStatus(Format(SCompilerStatusReadingFile, ['isunzlib.dll']));
           DecompressorDLL := CreateMemoryStreamFromFile(CompilerDir + 'isunzlib.dll',

+ 7 - 7
Projects/Src/Compression.Base.pas

@@ -340,6 +340,13 @@ begin
   inherited;
 end;
 
+procedure TCompressedBlockWriter.InitEncryption(const CryptKey: TSetupEncryptionKey;
+  const EncryptionBaseNonce: TSetupEncryptionNonce; const UniqueIndex: Integer);
+begin
+  InitCryptContext(CryptKey, EncryptionBaseNonce, UniqueIndex, FCryptContext);
+  FEncrypt := True;
+end;
+
 procedure TCompressedBlockWriter.FlushOutputBuffer;
 { Flushes contents of FOutBuffer into the file, with a preceding CRC }
 var
@@ -356,13 +363,6 @@ begin
   FOutBufferCount := 0;
 end;
 
-procedure TCompressedBlockWriter.InitEncryption(const CryptKey: TSetupEncryptionKey;
-  const EncryptionBaseNonce: TSetupEncryptionNonce; const UniqueIndex: Integer);
-begin
-  InitCryptContext(CryptKey, EncryptionBaseNonce, UniqueIndex, FCryptContext);
-  FEncrypt := True;
-end;
-
 procedure TCompressedBlockWriter.CompressorWriteProc(const Buffer; Count: Longint);
 var
   P: ^Byte;

+ 2 - 2
Projects/Src/Setup.FileExtractor.pas

@@ -66,7 +66,7 @@ const
      TLZMA2Decompressor);
 begin
   if FFileExtractor = nil then
-    FFileExtractor := TFileExtractor.Create(DecompClasses[SetupHeader.CompressMethod]);
+    FFileExtractor := TFileExtractor.Create(DecompClasses[SetupMainHeader.CompressMethod]);
   Result := FFileExtractor;
 end;
 
@@ -192,7 +192,7 @@ procedure TFileExtractor.SeekTo(const FL: TSetupFileLocationEntry;
   procedure InitDecryption;
   begin
     { Recreate the unique nonce from the base nonce }
-    var Nonce := SetupHeader.EncryptionBaseNonce;
+    var Nonce := SetupMainHeader.EncryptionBaseNonce;
     Nonce.RandomXorStartOffset := Nonce.RandomXorStartOffset xor FChunkStartOffset;
     Nonce.RandomXorFirstSlice := Nonce.RandomXorFirstSlice xor FChunkFirstSlice;
 

+ 27 - 26
Projects/Src/Setup.MainFunc.pas

@@ -105,6 +105,7 @@ var
   UninstallSilent: Boolean;
 
   { Variables read in from the SETUP.0 file }
+  SetupMainHeader: TSetupMainHeader;
   SetupHeader: TSetupHeader;
   LangOptions: TSetupLanguageEntry;
   Entries: array[TEntryType] of TList;
@@ -2653,7 +2654,7 @@ var
     DecompressorDLLHandle := SafeLoadLibrary(Filename, SEM_NOOPENFILEERRORBOX);
     if DecompressorDLLHandle = 0 then
       InternalError(Format('Failed to load DLL "%s"', [Filename]));
-    case SetupHeader.CompressMethod of
+    case SetupMainHeader.CompressMethod of
       cmZip:
         if not ZlibInitDecompressFunctions(DecompressorDLLHandle) then
           InternalError('ZlibInitDecompressFunctions failed');
@@ -2733,15 +2734,15 @@ var
     if NeedPassword and (InitPassword <> '') then begin
       var PasswordOk := False;
       var S := InitPassword;
-      GenerateEncryptionKey(S, SetupHeader.EncryptionKDFSalt, SetupHeader.EncryptionKDFIterations, CryptKey);
+      GenerateEncryptionKey(S, SetupMainHeader.EncryptionKDFSalt, SetupMainHeader.EncryptionKDFIterations, CryptKey);
       if shPassword in SetupHeader.Options then
-        PasswordOk := TestPassword(CryptKey, SetupHeader.EncryptionBaseNonce, SetupHeader.PasswordTest);
+        PasswordOk := TestPassword(CryptKey, SetupMainHeader.EncryptionBaseNonce, SetupMainHeader.PasswordTest);
       if not PasswordOk and (CodeRunner <> nil) then
         PasswordOk := CodeRunner.RunBooleanFunctions('CheckPassword', [S], bcTrue, False, PasswordOk);
 
       if PasswordOk then begin
         Result := False;
-        if SetupHeader.EncryptionUse <> euNone then
+        if SetupMainHeader.EncryptionUse <> euNone then
           FileExtractor.CryptKey := CryptKey;
       end;
     end;
@@ -3094,26 +3095,26 @@ begin
       AbortInit(msgSetupFileCorruptOrWrongVer);
     if TestID <> SetupID then
       AbortInit(msgSetupFileCorruptOrWrongVer);
-    try
-      var CryptKey: TSetupEncryptionKey;
-      SetupFile.Read(SetupHeader.EncryptionUse, SizeOf(SetupHeader.EncryptionUse));
-      if SetupHeader.EncryptionUse = euFull then begin
-        SetupFile.Read(SetupHeader.EncryptionKDFSalt, SizeOf(SetupHeader.EncryptionKDFSalt));
-        SetupFile.Read(SetupHeader.EncryptionKDFIterations, SizeOf(SetupHeader.EncryptionKDFIterations));
-        SetupFile.Read(SetupHeader.EncryptionBaseNonce, SizeOf(SetupHeader.EncryptionBaseNonce));
-        SetupFile.Read(SetupHeader.PasswordTest, SizeOf(SetupHeader.PasswordTest));
-        { FileExtractor (a function called early to initialize its CryptKey) requires CompressMethod to be set }
-        SetupFile.Read(SetupHeader.CompressMethod, SizeOf(SetupHeader.CompressMethod));
-        { HandleInitPassword requires this }
-        SetupHeader.Options := SetupHeader.Options + [shPassword];
-        if HandleInitPassword(True, CryptKey) then { HandleInitPassword returns True on failure }
-          AbortInit(msgIncorrectPassword)
-      end;
 
+    var SetupMainHeaderCRC: Longint;
+    SetupFile.Read(SetupMainHeaderCRC, SizeOf(SetupMainHeaderCRC));
+    SetupFile.Read(SetupMainHeader, SizeOf(SetupMainHeader));
+    if SetupMainHeaderCRC <> GetCRC32(SetupMainHeader, SizeOf(SetupMainHeader)) then
+      AbortInit(msgSetupFileCorruptOrWrongVer);
+
+    var CryptKey: TSetupEncryptionKey;
+    if SetupMainHeader.EncryptionUse = euFull then begin
+      { HandleInitPassword requires this }
+      SetupHeader.Options := SetupHeader.Options + [shPassword];
+      if HandleInitPassword(True, CryptKey) then { HandleInitPassword returns True on failure }
+        AbortInit(msgIncorrectPassword)
+    end;
+
+    try
       var Reader := TCompressedBlockReader.Create(SetupFile, TLZMA1Decompressor);
       try
-        if SetupHeader.EncryptionUse = euFull then
-          Reader.InitDecryption(CryptKey, SetupHeader.EncryptionBaseNonce, -2);
+        if SetupMainHeader.EncryptionUse = euFull then
+          Reader.InitDecryption(CryptKey, SetupMainHeader.EncryptionBaseNonce, -2);
 
         { Header }
         SECompressedBlockRead(Reader, SetupHeader, SizeOf(SetupHeader),
@@ -3195,7 +3196,7 @@ begin
         LogCompatibilityMode;
         LogWindowsVersion;
 
-        NeedPassword := (SetupHeader.EncryptionUse <> euFull) and (shPassword in SetupHeader.Options);
+        NeedPassword := (SetupMainHeader.EncryptionUse <> euFull) and (shPassword in SetupHeader.Options);
         NeedSerial := False;
         NeedsRestart := shAlwaysRestart in SetupHeader.Options;
 
@@ -3252,7 +3253,7 @@ begin
           WizardSmallImages.Add(ReadWizardImage(Reader));
         { Decompressor DLL }
         DecompressorDLL := nil;
-        if SetupHeader.CompressMethod in [cmZip, cmBzip] then begin
+        if SetupMainHeader.CompressMethod in [cmZip, cmBzip] then begin
           DecompressorDLL := TMemoryStream.Create;
           ReadFileIntoStream(Reader, DecompressorDLL);
         end;
@@ -3267,8 +3268,8 @@ begin
       end;
       Reader := TCompressedBlockReader.Create(SetupFile, TLZMA1Decompressor);
       try
-        if SetupHeader.EncryptionUse = euFull then
-          Reader.InitDecryption(CryptKey, SetupHeader.EncryptionBaseNonce, -3);
+        if SetupMainHeader.EncryptionUse = euFull then
+          Reader.InitDecryption(CryptKey, SetupMainHeader.EncryptionBaseNonce, -3);
 
         { File location entries }
         ReadEntriesWithoutVersion(Reader, seFileLocation, SetupHeader.NumFileLocationEntries,
@@ -3345,7 +3346,7 @@ begin
   LoadSHFolderDLL;
 
   { Save DecompressorDLL stream as "_isdecmp.dll" in TempInstallDir, and load it }
-  if SetupHeader.CompressMethod in [cmZip, cmBzip] then
+  if SetupMainHeader.CompressMethod in [cmZip, cmBzip] then
     LoadDecompressorDLL;
 
   { Save SevenZipDll stream as "_is7z.dll" in TempInstallDir, and load it }

+ 3 - 3
Projects/Src/Setup.WizardForm.pas

@@ -2432,19 +2432,19 @@ procedure TWizardForm.NextButtonClick(Sender: TObject);
     var SaveCursor := GetCursor;
     SetCursor(LoadCursor(0, IDC_WAIT));
     try
-      GenerateEncryptionKey(S, SetupHeader.EncryptionKDFSalt, SetupHeader.EncryptionKDFIterations, CryptKey);
+      GenerateEncryptionKey(S, SetupMainHeader.EncryptionKDFSalt, SetupMainHeader.EncryptionKDFIterations, CryptKey);
     finally
       SetCursor(SaveCursor);
     end;
 
     if shPassword in SetupHeader.Options then
-      Result := TestPassword(CryptKey, SetupHeader.EncryptionBaseNonce, SetupHeader.PasswordTest);
+      Result := TestPassword(CryptKey, SetupMainHeader.EncryptionBaseNonce, SetupMainHeader.PasswordTest);
     if not Result and (CodeRunner <> nil) then
       Result := CodeRunner.RunBooleanFunctions('CheckPassword', [S], bcTrue, False, Result);
 
     if Result then begin
       NeedPassword := False;
-      if SetupHeader.EncryptionUse <> euNone then
+      if SetupMainHeader.EncryptionUse <> euNone then
         FileExtractor.CryptKey := CryptKey;
       PasswordEdit.Text := '';
     end else begin

+ 12 - 6
Projects/Src/Shared.Struct.pas

@@ -86,6 +86,18 @@ const
   SetupProcessorArchitectureNames: array[TSetupProcessorArchitecture] of String =
     ('Unknown', 'x86', 'x64', 'Arm32', 'Arm64');
 
+type
+  { Should not contain strings }
+  TSetupMainHeader = packed record
+    PasswordTest: Integer;
+    EncryptionUse: TSetupEncryptionUse;
+    EncryptionKDFSalt: TSetupKDFSalt;
+    EncryptionKDFIterations: Integer;
+    EncryptionBaseNonce: TSetupEncryptionNonce;
+    { FileExtractor (a function called early to initialize its CryptKey) requires CompressMethod to be set }
+    CompressMethod: TSetupCompressMethod;
+  end;
+
 const
   SetupHeaderStrings = 34;
   SetupHeaderAnsiStrings = 4;
@@ -110,11 +122,6 @@ type
     WizardStyle: TSetupWizardStyle;
     WizardSizePercentX, WizardSizePercentY: Integer;
     WizardImageAlphaFormat: (afIgnored, afDefined, afPremultiplied); // Must be same as Graphics.TAlphaFormat
-    PasswordTest: Integer;
-    EncryptionUse: TSetupEncryptionUse;
-    EncryptionKDFSalt: TSetupKDFSalt;
-    EncryptionKDFIterations: Integer;
-    EncryptionBaseNonce: TSetupEncryptionNonce;
     ExtraDiskSpaceRequired: Integer64;
     SlicesPerDisk: Integer;
     UninstallLogMode: (lmAppend, lmNew, lmOverwrite);
@@ -123,7 +130,6 @@ type
     PrivilegesRequiredOverridesAllowed: TSetupPrivilegesRequiredOverrides;
     ShowLanguageDialog: (slYes, slNo, slAuto);
     LanguageDetectionMethod: TSetupLanguageDetectionMethod;
-    CompressMethod: TSetupCompressMethod;
     DisableDirPage, DisableProgramGroupPage: TSetupDisablePage;
     UninstallDisplaySize: Integer64;
     Options: set of TSetupHeaderOption;