Просмотр исходного кода

Make it so CompressMethod doesnt have to be in the initial header, rename the header from TSetupMainHeader to TSetupEncryptionHeader, and move PasswordTest to a more logical place.

Martijn Laan 1 месяц назад
Родитель
Сommit
f71709902c

+ 10 - 10
Projects/SetupLdr.dpr

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

+ 28 - 28
Projects/Src/Compiler.SetupCompiler.pas

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

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

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

+ 28 - 21
Projects/Src/Setup.MainFunc.pas

@@ -105,7 +105,7 @@ var
   UninstallSilent: Boolean;
   UninstallSilent: Boolean;
 
 
   { Variables read in from the SETUP.0 file }
   { Variables read in from the SETUP.0 file }
-  SetupMainHeader: TSetupMainHeader;
+  SetupEncryptionHeader: TSetupEncryptionHeader;
   SetupHeader: TSetupHeader;
   SetupHeader: TSetupHeader;
   LangOptions: TSetupLanguageEntry;
   LangOptions: TSetupLanguageEntry;
   Entries: array[TEntryType] of TList;
   Entries: array[TEntryType] of TList;
@@ -2654,7 +2654,7 @@ var
     DecompressorDLLHandle := SafeLoadLibrary(Filename, SEM_NOOPENFILEERRORBOX);
     DecompressorDLLHandle := SafeLoadLibrary(Filename, SEM_NOOPENFILEERRORBOX);
     if DecompressorDLLHandle = 0 then
     if DecompressorDLLHandle = 0 then
       InternalError(Format('Failed to load DLL "%s"', [Filename]));
       InternalError(Format('Failed to load DLL "%s"', [Filename]));
-    case SetupMainHeader.CompressMethod of
+    case SetupHeader.CompressMethod of
       cmZip:
       cmZip:
         if not ZlibInitDecompressFunctions(DecompressorDLLHandle) then
         if not ZlibInitDecompressFunctions(DecompressorDLLHandle) then
           InternalError('ZlibInitDecompressFunctions failed');
           InternalError('ZlibInitDecompressFunctions failed');
@@ -2725,7 +2725,8 @@ var
     end;
     end;
   end;
   end;
 
 
-  function HandleInitPassword(const NeedPassword: Boolean; out CryptKey: TSetupEncryptionKey): Boolean; overload;
+  function HandleInitPassword(const NeedPassword, AllowSetFileExtractorCryptKey: Boolean;
+    out CryptKey: TSetupEncryptionKey): Boolean; overload;
   { Handles InitPassword and returns the updated value of NeedPassword }
   { Handles InitPassword and returns the updated value of NeedPassword }
   { Also see WizardForm.CheckPassword }
   { Also see WizardForm.CheckPassword }
   begin
   begin
@@ -2734,15 +2735,15 @@ var
     if NeedPassword and (InitPassword <> '') then begin
     if NeedPassword and (InitPassword <> '') then begin
       var PasswordOk := False;
       var PasswordOk := False;
       var S := InitPassword;
       var S := InitPassword;
-      GenerateEncryptionKey(S, SetupMainHeader.EncryptionKDFSalt, SetupMainHeader.EncryptionKDFIterations, CryptKey);
+      GenerateEncryptionKey(S, SetupEncryptionHeader.EncryptionKDFSalt, SetupEncryptionHeader.EncryptionKDFIterations, CryptKey);
       if shPassword in SetupHeader.Options then
       if shPassword in SetupHeader.Options then
-        PasswordOk := TestPassword(CryptKey, SetupMainHeader.EncryptionBaseNonce, SetupMainHeader.PasswordTest);
+        PasswordOk := TestPassword(CryptKey, SetupEncryptionHeader.EncryptionBaseNonce, SetupEncryptionHeader.PasswordTest);
       if not PasswordOk and (CodeRunner <> nil) then
       if not PasswordOk and (CodeRunner <> nil) then
         PasswordOk := CodeRunner.RunBooleanFunctions('CheckPassword', [S], bcTrue, False, PasswordOk);
         PasswordOk := CodeRunner.RunBooleanFunctions('CheckPassword', [S], bcTrue, False, PasswordOk);
 
 
       if PasswordOk then begin
       if PasswordOk then begin
         Result := False;
         Result := False;
-        if SetupMainHeader.EncryptionUse <> euNone then
+        if AllowSetFileExtractorCryptKey and (SetupEncryptionHeader.EncryptionUse <> euNone) then
           FileExtractor.CryptKey := CryptKey;
           FileExtractor.CryptKey := CryptKey;
       end;
       end;
     end;
     end;
@@ -2751,7 +2752,7 @@ var
   function HandleInitPassword(const NeedPassword: Boolean): Boolean; overload;
   function HandleInitPassword(const NeedPassword: Boolean): Boolean; overload;
   begin
   begin
     var CryptKey: TSetupEncryptionKey;
     var CryptKey: TSetupEncryptionKey;
-    Result := HandleInitPassword(NeedPassword, CryptKey);
+    Result := HandleInitPassword(NeedPassword, True, CryptKey);
   end;
   end;
 
 
   procedure SetupInstallMode;
   procedure SetupInstallMode;
@@ -3096,30 +3097,36 @@ begin
     if TestID <> SetupID then
     if TestID <> SetupID then
       AbortInit(msgSetupFileCorruptOrWrongVer);
       AbortInit(msgSetupFileCorruptOrWrongVer);
 
 
-    var SetupMainHeaderCRC: Longint;
-    SetupFile.Read(SetupMainHeaderCRC, SizeOf(SetupMainHeaderCRC));
-    SetupFile.Read(SetupMainHeader, SizeOf(SetupMainHeader));
-    if SetupMainHeaderCRC <> GetCRC32(SetupMainHeader, SizeOf(SetupMainHeader)) then
+    var SetupEncryptionHeaderCRC: Longint;
+    SetupFile.Read(SetupEncryptionHeaderCRC, SizeOf(SetupEncryptionHeaderCRC));
+    SetupFile.Read(SetupEncryptionHeader, SizeOf(SetupEncryptionHeader));
+    if SetupEncryptionHeaderCRC <> GetCRC32(SetupEncryptionHeader, SizeOf(SetupEncryptionHeader)) then
       AbortInit(msgSetupFileCorruptOrWrongVer);
       AbortInit(msgSetupFileCorruptOrWrongVer);
 
 
     var CryptKey: TSetupEncryptionKey;
     var CryptKey: TSetupEncryptionKey;
-    if SetupMainHeader.EncryptionUse = euFull then begin
+    if SetupEncryptionHeader.EncryptionUse = euFull then begin
       { HandleInitPassword requires this }
       { HandleInitPassword requires this }
       SetupHeader.Options := SetupHeader.Options + [shPassword];
       SetupHeader.Options := SetupHeader.Options + [shPassword];
-      if HandleInitPassword(True, CryptKey) then { HandleInitPassword returns True on failure }
+      { Specifying False for AllowSetFileExtractorCryptKey because FileExtractor (a function!)
+        requires SetupHeader.CompressMethod to be set, so delaying until SetupHeader is read below }
+      if HandleInitPassword(True, False, CryptKey) then { HandleInitPassword returns True on failure }
         AbortInit(msgIncorrectPassword)
         AbortInit(msgIncorrectPassword)
     end;
     end;
 
 
     try
     try
       var Reader := TCompressedBlockReader.Create(SetupFile, TLZMA1Decompressor);
       var Reader := TCompressedBlockReader.Create(SetupFile, TLZMA1Decompressor);
       try
       try
-        if SetupMainHeader.EncryptionUse = euFull then
-          Reader.InitDecryption(CryptKey, SetupMainHeader.EncryptionBaseNonce, -2);
+        if SetupEncryptionHeader.EncryptionUse = euFull then
+          Reader.InitDecryption(CryptKey, SetupEncryptionHeader.EncryptionBaseNonce, -2);
 
 
         { Header }
         { Header }
         SECompressedBlockRead(Reader, SetupHeader, SizeOf(SetupHeader),
         SECompressedBlockRead(Reader, SetupHeader, SizeOf(SetupHeader),
           SetupHeaderStrings, SetupHeaderAnsiStrings);
           SetupHeaderStrings, SetupHeaderAnsiStrings);
-      { Language entries }
+
+        if SetupEncryptionHeader.EncryptionUse = euFull then
+          FileExtractor.CryptKey := CryptKey; { See above }
+
+        { Language entries }
         ReadEntriesWithoutVersion(Reader, seLanguage, SetupHeader.NumLanguageEntries,
         ReadEntriesWithoutVersion(Reader, seLanguage, SetupHeader.NumLanguageEntries,
           SizeOf(TSetupLanguageEntry));
           SizeOf(TSetupLanguageEntry));
         { CustomMessage entries }
         { CustomMessage entries }
@@ -3196,7 +3203,7 @@ begin
         LogCompatibilityMode;
         LogCompatibilityMode;
         LogWindowsVersion;
         LogWindowsVersion;
 
 
-        NeedPassword := (SetupMainHeader.EncryptionUse <> euFull) and (shPassword in SetupHeader.Options);
+        NeedPassword := (SetupEncryptionHeader.EncryptionUse <> euFull) and (shPassword in SetupHeader.Options);
         NeedSerial := False;
         NeedSerial := False;
         NeedsRestart := shAlwaysRestart in SetupHeader.Options;
         NeedsRestart := shAlwaysRestart in SetupHeader.Options;
 
 
@@ -3253,7 +3260,7 @@ begin
           WizardSmallImages.Add(ReadWizardImage(Reader));
           WizardSmallImages.Add(ReadWizardImage(Reader));
         { Decompressor DLL }
         { Decompressor DLL }
         DecompressorDLL := nil;
         DecompressorDLL := nil;
-        if SetupMainHeader.CompressMethod in [cmZip, cmBzip] then begin
+        if SetupHeader.CompressMethod in [cmZip, cmBzip] then begin
           DecompressorDLL := TMemoryStream.Create;
           DecompressorDLL := TMemoryStream.Create;
           ReadFileIntoStream(Reader, DecompressorDLL);
           ReadFileIntoStream(Reader, DecompressorDLL);
         end;
         end;
@@ -3268,8 +3275,8 @@ begin
       end;
       end;
       Reader := TCompressedBlockReader.Create(SetupFile, TLZMA1Decompressor);
       Reader := TCompressedBlockReader.Create(SetupFile, TLZMA1Decompressor);
       try
       try
-        if SetupMainHeader.EncryptionUse = euFull then
-          Reader.InitDecryption(CryptKey, SetupMainHeader.EncryptionBaseNonce, -3);
+        if SetupEncryptionHeader.EncryptionUse = euFull then
+          Reader.InitDecryption(CryptKey, SetupEncryptionHeader.EncryptionBaseNonce, -3);
 
 
         { File location entries }
         { File location entries }
         ReadEntriesWithoutVersion(Reader, seFileLocation, SetupHeader.NumFileLocationEntries,
         ReadEntriesWithoutVersion(Reader, seFileLocation, SetupHeader.NumFileLocationEntries,
@@ -3346,7 +3353,7 @@ begin
   LoadSHFolderDLL;
   LoadSHFolderDLL;
 
 
   { Save DecompressorDLL stream as "_isdecmp.dll" in TempInstallDir, and load it }
   { Save DecompressorDLL stream as "_isdecmp.dll" in TempInstallDir, and load it }
-  if SetupMainHeader.CompressMethod in [cmZip, cmBzip] then
+  if SetupHeader.CompressMethod in [cmZip, cmBzip] then
     LoadDecompressorDLL;
     LoadDecompressorDLL;
 
 
   { Save SevenZipDll stream as "_is7z.dll" in TempInstallDir, and load it }
   { 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;
     var SaveCursor := GetCursor;
     SetCursor(LoadCursor(0, IDC_WAIT));
     SetCursor(LoadCursor(0, IDC_WAIT));
     try
     try
-      GenerateEncryptionKey(S, SetupMainHeader.EncryptionKDFSalt, SetupMainHeader.EncryptionKDFIterations, CryptKey);
+      GenerateEncryptionKey(S, SetupEncryptionHeader.EncryptionKDFSalt, SetupEncryptionHeader.EncryptionKDFIterations, CryptKey);
     finally
     finally
       SetCursor(SaveCursor);
       SetCursor(SaveCursor);
     end;
     end;
 
 
     if shPassword in SetupHeader.Options then
     if shPassword in SetupHeader.Options then
-      Result := TestPassword(CryptKey, SetupMainHeader.EncryptionBaseNonce, SetupMainHeader.PasswordTest);
+      Result := TestPassword(CryptKey, SetupEncryptionHeader.EncryptionBaseNonce, SetupEncryptionHeader.PasswordTest);
     if not Result and (CodeRunner <> nil) then
     if not Result and (CodeRunner <> nil) then
       Result := CodeRunner.RunBooleanFunctions('CheckPassword', [S], bcTrue, False, Result);
       Result := CodeRunner.RunBooleanFunctions('CheckPassword', [S], bcTrue, False, Result);
 
 
     if Result then begin
     if Result then begin
       NeedPassword := False;
       NeedPassword := False;
-      if SetupMainHeader.EncryptionUse <> euNone then
+      if SetupEncryptionHeader.EncryptionUse <> euNone then
         FileExtractor.CryptKey := CryptKey;
         FileExtractor.CryptKey := CryptKey;
       PasswordEdit.Text := '';
       PasswordEdit.Text := '';
     end else begin
     end else begin

+ 3 - 4
Projects/Src/Shared.Struct.pas

@@ -88,14 +88,12 @@ const
 
 
 type
 type
   { Should not contain strings }
   { Should not contain strings }
-  TSetupMainHeader = packed record
-    PasswordTest: Integer;
+  TSetupEncryptionHeader = packed record
     EncryptionUse: TSetupEncryptionUse;
     EncryptionUse: TSetupEncryptionUse;
     EncryptionKDFSalt: TSetupKDFSalt;
     EncryptionKDFSalt: TSetupKDFSalt;
     EncryptionKDFIterations: Integer;
     EncryptionKDFIterations: Integer;
     EncryptionBaseNonce: TSetupEncryptionNonce;
     EncryptionBaseNonce: TSetupEncryptionNonce;
-    { FileExtractor (a function called early to initialize its CryptKey) requires CompressMethod to be set }
-    CompressMethod: TSetupCompressMethod;
+    PasswordTest: Integer;
   end;
   end;
 
 
 const
 const
@@ -130,6 +128,7 @@ type
     PrivilegesRequiredOverridesAllowed: TSetupPrivilegesRequiredOverrides;
     PrivilegesRequiredOverridesAllowed: TSetupPrivilegesRequiredOverrides;
     ShowLanguageDialog: (slYes, slNo, slAuto);
     ShowLanguageDialog: (slYes, slNo, slAuto);
     LanguageDetectionMethod: TSetupLanguageDetectionMethod;
     LanguageDetectionMethod: TSetupLanguageDetectionMethod;
+    CompressMethod: TSetupCompressMethod;
     DisableDirPage, DisableProgramGroupPage: TSetupDisablePage;
     DisableDirPage, DisableProgramGroupPage: TSetupDisablePage;
     UninstallDisplaySize: Integer64;
     UninstallDisplaySize: Integer64;
     Options: set of TSetupHeaderOption;
     Options: set of TSetupHeaderOption;