Przeglądaj źródła

Merge branch 'main' into autoreload

Martijn Laan 1 miesiąc temu
rodzic
commit
340c9c500e

+ 43 - 0
.github/workflows/build2.yml

@@ -0,0 +1,43 @@
+name: build2
+
+on:
+  push:
+  workflow_dispatch:
+
+env:
+  HOME: "${{github.workspace}}\\home"
+
+jobs:
+  build2:
+    # Only set the topic `has-issrc-build2-env` if the secrets are available
+    if: contains(github.event.repository.topics, 'has-issrc-build2-env')
+    runs-on: windows-latest
+    steps:
+      - uses: actions/checkout@v3
+        with:
+          submodules: true
+      - name: Initialize build environment
+        env:
+          ISSRC_BUILD2_ENV_ZIP_PASSWORD: ${{ secrets.ISSRC_BUILD2_ENV_ZIP_PASSWORD }}
+          ISSRC_BUILD2_ENV_ZIP_URL: ${{ secrets.ISSRC_BUILD2_ENV_ZIP_URL }}
+        run: |
+          (New-Object Net.WebClient).DownloadFile($env:ISSRC_BUILD2_ENV_ZIP_URL, "issrc-build-env.zip")
+          & "C:\\Program Files\\7-Zip\\7z.exe" x -oissrc-build-env -p"$env:ISSRC_BUILD2_ENV_ZIP_PASSWORD" issrc-build-env.zip
+          if (!(Test-Path issrc-build-env\bin\dcc32.exe)) {
+            Write-Host "Failed to extract dcc32.exe"
+            Exit 1
+          }
+          Remove-Item issrc-build-env.zip
+          $DELPHIXEROOT = (Get-Item .\issrc-build-env).FullName
+          "DELPHIXEROOT=$DELPHIXEROOT" | Out-File -NoNewLine -Encoding ascii -Append "$env:GITHUB_ENV"
+      - name: Build issrc
+        run: |
+          "set DELPHIXEROOT=$env:DELPHIXEROOT" | Out-File -Encoding ascii compilesettings.bat
+          "set ISSIGTOOL_KEY_FILE=${{github.workspace}}\mykey.isprivatekey" | Out-File -NoNewline -Encoding ascii -Append compilesettings.bat
+          "set DELPHIXEROOT=$env:DELPHIXEROOT" | Out-File -NoNewline -Encoding ascii ISHelp\ISHelpGen\compilesettings.bat
+          "set HHCEXE=%ProgramFiles(x86)%\HTML Help Workshop\hhc.exe" | Out-File -NoNewline -Encoding ascii ISHelp\compilesettings.bat
+          .\build.bat
+      - name: Clean up temporary files
+        if: always()
+        shell: bash
+        run: rm -rf mykey.isprivatekey

+ 8 - 9
Components/BitmapButton.pas

@@ -26,8 +26,6 @@ type
   private
   private
     FFocusBorderWidthHeight: Integer;
     FFocusBorderWidthHeight: Integer;
     FImpl: TBitmapImageImplementation;
     FImpl: TBitmapImageImplementation;
-    FOnClick: TNotifyEvent;
-    FOnDblClick: TNotifyEvent;
     procedure SetBackColor(Value: TColor);
     procedure SetBackColor(Value: TColor);
     procedure SetBitmap(Value: TBitmap);
     procedure SetBitmap(Value: TBitmap);
     procedure SetCenter(Value: Boolean);
     procedure SetCenter(Value: Boolean);
@@ -64,8 +62,8 @@ type
     property TabOrder;
     property TabOrder;
     property TabStop default True;
     property TabStop default True;
     property Visible;
     property Visible;
-    property OnClick: TNotifyEvent read FOnClick write FOnClick;
-    property OnDblClick: TNotifyEvent read FOnDblClick write FOnDblClick;
+    property OnClick;
+    property OnDblClick;
     property OnPaint: TPaintEvent read FImpl.OnPaint write FImpl.OnPaint;
     property OnPaint: TPaintEvent read FImpl.OnPaint write FImpl.OnPaint;
   end;
   end;
 
 
@@ -81,7 +79,7 @@ end;
 constructor TBitmapButton.Create(AOwner: TComponent);
 constructor TBitmapButton.Create(AOwner: TComponent);
 begin
 begin
   inherited;
   inherited;
-  ControlStyle := ControlStyle + [csReplicatable];
+  ControlStyle := ControlStyle + [csReplicatable] - [csClickEvents];
   { Using a fixed focus border width/height to avoid design problems between systems }
   { Using a fixed focus border width/height to avoid design problems between systems }
   FFocusBorderWidthHeight := 2;
   FFocusBorderWidthHeight := 2;
   const DoubleFBWH = 2*FFocusBorderWidthHeight;
   const DoubleFBWH = 2*FFocusBorderWidthHeight;
@@ -96,6 +94,7 @@ procedure TBitmapButton.CreateParams(var Params: TCreateParams);
 begin
 begin
   inherited;
   inherited;
   CreateSubClass(Params, 'BUTTON');
   CreateSubClass(Params, 'BUTTON');
+  Params.Style := Params.Style or BS_NOTIFY; { For BN_DBLCLK }
 end;
 end;
 
 
 destructor TBitmapButton.Destroy;
 destructor TBitmapButton.Destroy;
@@ -184,10 +183,10 @@ end;
 
 
 procedure TBitmapButton.CNCommand(var Message: TWMCommand);
 procedure TBitmapButton.CNCommand(var Message: TWMCommand);
 begin
 begin
-  if (Message.NotifyCode = BN_CLICKED) and Assigned(FOnClick) then
-    FOnClick(Self)
-  else if (Message.NotifyCode = BN_DBLCLK) and Assigned(FOnDblClick) then
-    FOnDblClick(Self);
+  if (Message.NotifyCode = BN_CLICKED) then
+    Click
+  else if (Message.NotifyCode = BN_DBLCLK) then
+    DblClick;
 end;
 end;
 
 
 end.
 end.

+ 1 - 1
Components/ISSigFunc.pas

@@ -102,7 +102,7 @@ function CalcHashToSign(const AIncludeFileNameAndTag: Boolean; const AFileName:
   procedure SHA256UpdateWithString(var Context: TSHA256Context; const S: String);
   procedure SHA256UpdateWithString(var Context: TSHA256Context; const S: String);
   begin
   begin
     const U = UTF8String(S);
     const U = UTF8String(S);
-    const N: Int32 = Length(U);
+    const N = UInt32(Length(U));
     SHA256Update(Context, N, SizeOf(N));
     SHA256Update(Context, N, SizeOf(N));
     if N > 0 then
     if N > 0 then
       SHA256Update(Context, Pointer(U)^, N*SizeOf(U[1]));
       SHA256Update(Context, Pointer(U)^, N*SizeOf(U[1]));

+ 10 - 5
Projects/Src/Compression.SevenZipDLLDecoder.pas

@@ -214,16 +214,19 @@ type
 
 
 { Helper functions }
 { Helper functions }
 
 
-procedure SevenZipWin32Error(const FunctionName: String; ErrorCode: DWORD = 0); overload;
+procedure SevenZipWin32Error(const FunctionName: String; const ErrorCode: DWORD); overload;
 begin
 begin
-  if ErrorCode = 0 then
-    ErrorCode := GetLastError;
   const ExceptMessage = FmtSetupMessage(msgErrorFunctionFailedWithMessage,
   const ExceptMessage = FmtSetupMessage(msgErrorFunctionFailedWithMessage,
     [FunctionName, IntToStr(ErrorCode), Win32ErrorString(ErrorCode)]);
     [FunctionName, IntToStr(ErrorCode), Win32ErrorString(ErrorCode)]);
   const LogMessage = Format('Function %s returned error code %d', [FunctionName, ErrorCode]);
   const LogMessage = Format('Function %s returned error code %d', [FunctionName, ErrorCode]);
   SevenZipError(ExceptMessage, LogMessage);
   SevenZipError(ExceptMessage, LogMessage);
 end;
 end;
 
 
+procedure SevenZipWin32Error(const FunctionName: String); overload;
+begin
+  SevenZipWin32Error(FunctionName, GetLastError);
+end;
+
 function GetHandler(const Filename, NotFoundErrorMsg: String): TGUID; forward;
 function GetHandler(const Filename, NotFoundErrorMsg: String): TGUID; forward;
 
 
 const
 const
@@ -600,8 +603,9 @@ begin
         case WaitForSingleObject(ThreadHandle, 50) of
         case WaitForSingleObject(ThreadHandle, 50) of
           WAIT_OBJECT_0: Break;
           WAIT_OBJECT_0: Break;
           WAIT_TIMEOUT: HandleProgress; { This calls the user's OnExtractionProgress handler! }
           WAIT_TIMEOUT: HandleProgress; { This calls the user's OnExtractionProgress handler! }
+          WAIT_FAILED: SevenZipWin32Error('WaitForSingleObject');
         else
         else
-          SevenZipWin32Error('WaitForSingleObject');
+          SevenZipError('WaitForSingleObject returned unknown value');
         end;
         end;
       end;
       end;
     except
     except
@@ -1008,7 +1012,8 @@ begin
   try
   try
     F := TFileRedir.Create(DisableFsRedir, ArchiveFilename, fdOpenExisting, faRead, fsRead);
     F := TFileRedir.Create(DisableFsRedir, ArchiveFilename, fdOpenExisting, faRead, fsRead);
   except
   except
-    SevenZipWin32Error('CreateFile');
+    on E: EFileError do
+      SevenZipWin32Error('CreateFile', E.ErrorCode);
   end;
   end;
   const InStream: IInStream = TInStream.Create(F);
   const InStream: IInStream = TInStream.Create(F);
   var ScanSize := DefaultScanSize;
   var ScanSize := DefaultScanSize;

+ 32 - 38
Projects/Src/Setup.MainFunc.pas

@@ -2622,8 +2622,7 @@ var
     Abort;
     Abort;
   end;
   end;
 
 
-  procedure ReadFileIntoStream(const Stream: TStream;
-    const R: TCompressedBlockReader);
+  procedure ReadFileIntoStream(const Reader: TCompressedBlockReader; const Stream: TStream);
   type
   type
     PBuffer = ^TBuffer;
     PBuffer = ^TBuffer;
     TBuffer = array[0..8191] of Byte;
     TBuffer = array[0..8191] of Byte;
@@ -2633,11 +2632,11 @@ var
   begin
   begin
     New(Buf);
     New(Buf);
     try
     try
-      R.Read(BytesLeft, SizeOf(BytesLeft));
+      Reader.Read(BytesLeft, SizeOf(BytesLeft));
       while BytesLeft > 0 do begin
       while BytesLeft > 0 do begin
         Bytes := BytesLeft;
         Bytes := BytesLeft;
         if Bytes > SizeOf(Buf^) then Bytes := SizeOf(Buf^);
         if Bytes > SizeOf(Buf^) then Bytes := SizeOf(Buf^);
-        R.Read(Buf^, Bytes);
+        Reader.Read(Buf^, Bytes);
         Stream.WriteBuffer(Buf^, Bytes);
         Stream.WriteBuffer(Buf^, Bytes);
         Dec(BytesLeft, Bytes);
         Dec(BytesLeft, Bytes);
       end;
       end;
@@ -2646,13 +2645,11 @@ var
     end;
     end;
   end;
   end;
 
 
-  function ReadWizardImage(const R: TCompressedBlockReader): TBitmap;
-  var
-    MemStream: TMemoryStream;
+  function ReadWizardImage(const Reader: TCompressedBlockReader): TBitmap;
   begin
   begin
-    MemStream := TMemoryStream.Create;
+    const MemStream = TMemoryStream.Create;
     try
     try
-      ReadFileIntoStream(MemStream, R);
+      ReadFileIntoStream(Reader, MemStream);
       MemStream.Seek(0, soFromBeginning);
       MemStream.Seek(0, soFromBeginning);
       Result := TBitmap.Create;
       Result := TBitmap.Create;
       Result.AlphaFormat := TAlphaFormat(SetupHeader.WizardImageAlphaFormat);
       Result.AlphaFormat := TAlphaFormat(SetupHeader.WizardImageAlphaFormat);
@@ -2701,11 +2698,8 @@ var
     end;
     end;
   end;
   end;
 
 
-var
-  Reader: TCompressedBlockReader;
-
-  procedure ReadEntriesWithoutVersion(const EntryType: TEntryType;
-    const Count: Integer; const Size: Integer);
+  procedure ReadEntriesWithoutVersion(const Reader: TCompressedBlockReader;
+    const EntryType: TEntryType; const Count: Integer; const Size: Integer);
   var
   var
     I: Integer;
     I: Integer;
     P: Pointer;
     P: Pointer;
@@ -2719,8 +2713,8 @@ var
     end;
     end;
   end;
   end;
 
 
-  procedure ReadEntries(const EntryType: TEntryType; const Count: Integer;
-    const Size: Integer; const MinVersionOfs, OnlyBelowVersionOfs: Integer);
+  procedure ReadEntries(Reader: TCompressedBlockReader; const EntryType: TEntryType;
+    const Count: Integer; const Size: Integer; const MinVersionOfs, OnlyBelowVersionOfs: Integer);
   var
   var
     I: Integer;
     I: Integer;
     P: Pointer;
     P: Pointer;
@@ -3111,22 +3105,22 @@ begin
     if TestID <> SetupID then
     if TestID <> SetupID then
       AbortInit(msgSetupFileCorruptOrWrongVer);
       AbortInit(msgSetupFileCorruptOrWrongVer);
     try
     try
-      Reader := TCompressedBlockReader.Create(SetupFile, TLZMA1Decompressor);
+      var Reader := TCompressedBlockReader.Create(SetupFile, TLZMA1Decompressor);
       try
       try
         { Header }
         { Header }
         SECompressedBlockRead(Reader, SetupHeader, SizeOf(SetupHeader),
         SECompressedBlockRead(Reader, SetupHeader, SizeOf(SetupHeader),
           SetupHeaderStrings, SetupHeaderAnsiStrings);
           SetupHeaderStrings, SetupHeaderAnsiStrings);
         { Language entries }
         { Language entries }
-        ReadEntriesWithoutVersion(seLanguage, SetupHeader.NumLanguageEntries,
+        ReadEntriesWithoutVersion(Reader, seLanguage, SetupHeader.NumLanguageEntries,
           SizeOf(TSetupLanguageEntry));
           SizeOf(TSetupLanguageEntry));
         { CustomMessage entries }
         { CustomMessage entries }
-        ReadEntriesWithoutVersion(seCustomMessage, SetupHeader.NumCustomMessageEntries,
+        ReadEntriesWithoutVersion(Reader, seCustomMessage, SetupHeader.NumCustomMessageEntries,
           SizeOf(TSetupCustomMessageEntry));
           SizeOf(TSetupCustomMessageEntry));
         { Permission entries }
         { Permission entries }
-        ReadEntriesWithoutVersion(sePermission, SetupHeader.NumPermissionEntries,
+        ReadEntriesWithoutVersion(Reader, sePermission, SetupHeader.NumPermissionEntries,
           SizeOf(TSetupPermissionEntry));
           SizeOf(TSetupPermissionEntry));
         { Type entries }
         { Type entries }
-        ReadEntries(seType, SetupHeader.NumTypeEntries, SizeOf(TSetupTypeEntry),
+        ReadEntries(Reader, seType, SetupHeader.NumTypeEntries, SizeOf(TSetupTypeEntry),
           Integer(@PSetupTypeEntry(nil).MinVersion),
           Integer(@PSetupTypeEntry(nil).MinVersion),
           Integer(@PSetupTypeEntry(nil).OnlyBelowVersion));
           Integer(@PSetupTypeEntry(nil).OnlyBelowVersion));
 
 
@@ -3198,47 +3192,47 @@ begin
         NeedsRestart := shAlwaysRestart in SetupHeader.Options;
         NeedsRestart := shAlwaysRestart in SetupHeader.Options;
 
 
         { Component entries }
         { Component entries }
-        ReadEntries(seComponent, SetupHeader.NumComponentEntries, SizeOf(TSetupComponentEntry),
+        ReadEntries(Reader, seComponent, SetupHeader.NumComponentEntries, SizeOf(TSetupComponentEntry),
           -1, -1);
           -1, -1);
         { Task entries }
         { Task entries }
-        ReadEntries(seTask, SetupHeader.NumTaskEntries, SizeOf(TSetupTaskEntry),
+        ReadEntries(Reader, seTask, SetupHeader.NumTaskEntries, SizeOf(TSetupTaskEntry),
           -1, -1);
           -1, -1);
         { Dir entries }
         { Dir entries }
-        ReadEntries(seDir, SetupHeader.NumDirEntries, SizeOf(TSetupDirEntry),
+        ReadEntries(Reader, seDir, SetupHeader.NumDirEntries, SizeOf(TSetupDirEntry),
           Integer(@PSetupDirEntry(nil).MinVersion),
           Integer(@PSetupDirEntry(nil).MinVersion),
           Integer(@PSetupDirEntry(nil).OnlyBelowVersion));
           Integer(@PSetupDirEntry(nil).OnlyBelowVersion));
         { ISSigKey entries }
         { ISSigKey entries }
-        ReadEntriesWithoutVersion(seISSigKey, SetupHeader.NumISSigKeyEntries, SizeOf(TSetupISSigKeyEntry));
+        ReadEntriesWithoutVersion(Reader, seISSigKey, SetupHeader.NumISSigKeyEntries, SizeOf(TSetupISSigKeyEntry));
         { File entries }
         { File entries }
-        ReadEntries(seFile, SetupHeader.NumFileEntries, SizeOf(TSetupFileEntry),
+        ReadEntries(Reader, seFile, SetupHeader.NumFileEntries, SizeOf(TSetupFileEntry),
           Integer(@PSetupFileEntry(nil).MinVersion),
           Integer(@PSetupFileEntry(nil).MinVersion),
           Integer(@PSetupFileEntry(nil).OnlyBelowVersion));
           Integer(@PSetupFileEntry(nil).OnlyBelowVersion));
         { Icon entries }
         { Icon entries }
-        ReadEntries(seIcon, SetupHeader.NumIconEntries, SizeOf(TSetupIconEntry),
+        ReadEntries(Reader, seIcon, SetupHeader.NumIconEntries, SizeOf(TSetupIconEntry),
           Integer(@PSetupIconEntry(nil).MinVersion),
           Integer(@PSetupIconEntry(nil).MinVersion),
           Integer(@PSetupIconEntry(nil).OnlyBelowVersion));
           Integer(@PSetupIconEntry(nil).OnlyBelowVersion));
         { INI entries }
         { INI entries }
-        ReadEntries(seIni, SetupHeader.NumIniEntries, SizeOf(TSetupIniEntry),
+        ReadEntries(Reader, seIni, SetupHeader.NumIniEntries, SizeOf(TSetupIniEntry),
           Integer(@PSetupIniEntry(nil).MinVersion),
           Integer(@PSetupIniEntry(nil).MinVersion),
           Integer(@PSetupIniEntry(nil).OnlyBelowVersion));
           Integer(@PSetupIniEntry(nil).OnlyBelowVersion));
         { Registry entries }
         { Registry entries }
-        ReadEntries(seRegistry, SetupHeader.NumRegistryEntries, SizeOf(TSetupRegistryEntry),
+        ReadEntries(Reader, seRegistry, SetupHeader.NumRegistryEntries, SizeOf(TSetupRegistryEntry),
           Integer(@PSetupRegistryEntry(nil).MinVersion),
           Integer(@PSetupRegistryEntry(nil).MinVersion),
           Integer(@PSetupRegistryEntry(nil).OnlyBelowVersion));
           Integer(@PSetupRegistryEntry(nil).OnlyBelowVersion));
         { InstallDelete entries }
         { InstallDelete entries }
-        ReadEntries(seInstallDelete, SetupHeader.NumInstallDeleteEntries, SizeOf(TSetupDeleteEntry),
+        ReadEntries(Reader, seInstallDelete, SetupHeader.NumInstallDeleteEntries, SizeOf(TSetupDeleteEntry),
           Integer(@PSetupDeleteEntry(nil).MinVersion),
           Integer(@PSetupDeleteEntry(nil).MinVersion),
           Integer(@PSetupDeleteEntry(nil).OnlyBelowVersion));
           Integer(@PSetupDeleteEntry(nil).OnlyBelowVersion));
         { UninstallDelete entries }
         { UninstallDelete entries }
-        ReadEntries(seUninstallDelete, SetupHeader.NumUninstallDeleteEntries, SizeOf(TSetupDeleteEntry),
+        ReadEntries(Reader, seUninstallDelete, SetupHeader.NumUninstallDeleteEntries, SizeOf(TSetupDeleteEntry),
           Integer(@PSetupDeleteEntry(nil).MinVersion),
           Integer(@PSetupDeleteEntry(nil).MinVersion),
           Integer(@PSetupDeleteEntry(nil).OnlyBelowVersion));
           Integer(@PSetupDeleteEntry(nil).OnlyBelowVersion));
         { Run entries }
         { Run entries }
-        ReadEntries(seRun, SetupHeader.NumRunEntries, SizeOf(TSetupRunEntry),
+        ReadEntries(Reader, seRun, SetupHeader.NumRunEntries, SizeOf(TSetupRunEntry),
           Integer(@PSetupRunEntry(nil).MinVersion),
           Integer(@PSetupRunEntry(nil).MinVersion),
           Integer(@PSetupRunEntry(nil).OnlyBelowVersion));
           Integer(@PSetupRunEntry(nil).OnlyBelowVersion));
         { UninstallRun entries }
         { UninstallRun entries }
-        ReadEntries(seUninstallRun, SetupHeader.NumUninstallRunEntries, SizeOf(TSetupRunEntry),
+        ReadEntries(Reader, seUninstallRun, SetupHeader.NumUninstallRunEntries, SizeOf(TSetupRunEntry),
           Integer(@PSetupRunEntry(nil).MinVersion),
           Integer(@PSetupRunEntry(nil).MinVersion),
           Integer(@PSetupRunEntry(nil).OnlyBelowVersion));
           Integer(@PSetupRunEntry(nil).OnlyBelowVersion));
         { Wizard images }
         { Wizard images }
@@ -3252,13 +3246,13 @@ begin
         DecompressorDLL := nil;
         DecompressorDLL := nil;
         if SetupHeader.CompressMethod in [cmZip, cmBzip] then begin
         if SetupHeader.CompressMethod in [cmZip, cmBzip] then begin
           DecompressorDLL := TMemoryStream.Create;
           DecompressorDLL := TMemoryStream.Create;
-          ReadFileIntoStream(DecompressorDLL, Reader);
+          ReadFileIntoStream(Reader, DecompressorDLL);
         end;
         end;
         { SevenZip DLL }
         { SevenZip DLL }
         SevenZipDLL := nil;
         SevenZipDLL := nil;
         if SetupHeader.SevenZipLibraryName <> '' then begin
         if SetupHeader.SevenZipLibraryName <> '' then begin
           SevenZipDLL := TMemoryStream.Create;
           SevenZipDLL := TMemoryStream.Create;
-          ReadFileIntoStream(SevenZipDLL, Reader);
+          ReadFileIntoStream(Reader, SevenZipDLL);
         end;
         end;
       finally
       finally
         Reader.Free;
         Reader.Free;
@@ -3266,7 +3260,7 @@ begin
       Reader := TCompressedBlockReader.Create(SetupFile, TLZMA1Decompressor);
       Reader := TCompressedBlockReader.Create(SetupFile, TLZMA1Decompressor);
       try
       try
         { File location entries }
         { File location entries }
-        ReadEntriesWithoutVersion(seFileLocation, SetupHeader.NumFileLocationEntries,
+        ReadEntriesWithoutVersion(Reader, seFileLocation, SetupHeader.NumFileLocationEntries,
           SizeOf(TSetupFileLocationEntry));
           SizeOf(TSetupFileLocationEntry));
       finally
       finally
         Reader.Free;
         Reader.Free;
@@ -3339,11 +3333,11 @@ begin
   { Load system's "shfolder.dll", and load it }
   { Load system's "shfolder.dll", and load it }
   LoadSHFolderDLL;
   LoadSHFolderDLL;
 
 
-  { Extract "_isdecmp.dll" to TempInstallDir, and load it }
+  { Save DecompressorDLL stream as "_isdecmp.dll" in TempInstallDir, and load it }
   if SetupHeader.CompressMethod in [cmZip, cmBzip] then
   if SetupHeader.CompressMethod in [cmZip, cmBzip] then
     LoadDecompressorDLL;
     LoadDecompressorDLL;
 
 
-  { Extract "_is7z.dll" to TempInstallDir, and load it }
+  { Save SevenZipDll stream as "_is7z.dll" in TempInstallDir, and load it }
   if SetupHeader.SevenZipLibraryName <> '' then
   if SetupHeader.SevenZipLibraryName <> '' then
     LoadSevenZipDLL;
     LoadSevenZipDLL;
 
 

+ 24 - 16
Projects/Src/Shared.CommonFunc.pas

@@ -746,23 +746,31 @@ end;
 
 
 function GetTempDir: String;
 function GetTempDir: String;
 { Returns fully qualified path of the temporary directory, with trailing
 { Returns fully qualified path of the temporary directory, with trailing
-  backslash. This does not use the Win32 function GetTempPath, due to platform
-  differences. }
-label 1;
+  backslash. }
+var
+  GetTempPathFunc: function(nBufferLength: DWORD; lpBuffer: LPWSTR): DWORD; stdcall;
+  Buf: array[0..MAX_PATH] of Char;
 begin
 begin
-  Result := GetEnv('TMP');
-  if (Result <> '') and DirExists(Result) then
-    goto 1;
-  Result := GetEnv('TEMP');
-  if (Result <> '') and DirExists(Result) then
-    goto 1;
-  { Like Windows 2000's GetTempPath, return USERPROFILE when TMP and TEMP
-    are not set }
-  Result := GetEnv('USERPROFILE');
-  if (Result <> '') and DirExists(Result) then
-    goto 1;
-  Result := GetWinDir;
-1:Result := AddBackslash(PathExpand(Result));
+  { When available, GetTempPath2 is preferred as it returns a private
+    directory (typically C:\Windows\SystemTemp) when running as SYSTEM }
+  GetTempPathFunc := GetProcAddress(GetModuleHandle(kernel32),
+    PAnsiChar('GetTempPath2W'));
+  if not Assigned(GetTempPathFunc) then
+    GetTempPathFunc := GetTempPathW;
+
+  const Res = GetTempPathFunc(SizeOf(Buf) div SizeOf(Buf[0]), Buf);
+  if (Res > 0) and (Res < SizeOf(Buf) div SizeOf(Buf[0])) then begin
+    { The docs say the returned path is fully qualified and ends with a
+      backslash, but let's be really sure! }
+    Result := AddBackslash(PathExpand(Buf));
+    Exit;
+  end;
+
+  { We don't expect GetTempPath to ever fail or claim a larger buffer is
+    needed (docs say maximum possible return value is MAX_PATH+1), but if it
+    does, raise an exception as this function has no return value for failure }
+  raise Exception.CreateFmt('GetTempDir: GetTempPath failed (%u, %u)',
+    [Res, GetLastError]);
 end;
 end;
 
 
 function StringChangeEx(var S: String; const FromStr, ToStr: String;
 function StringChangeEx(var S: String; const FromStr, ToStr: String;

+ 6 - 2
README.md

@@ -266,8 +266,7 @@ cd /d C:\Program Files (x86)\Embarcadero\Studio\23.0
 	lib/win32/release/Winapi.*.dcu
 	lib/win32/release/Winapi.*.dcu
 ```
 ```
 
 
-Then, upload this encrypted file somewhere public, e.g. by attaching it to a comment
-in a GitHub issue. After that, add this URL as a new repository
+Then, upload this encrypted file somewhere public. After that, add its URL as a new repository
 [secret] (at https://github.com/YOUR-USER-NAME/issrc/settings/secrets/actions), under the name
 [secret] (at https://github.com/YOUR-USER-NAME/issrc/settings/secrets/actions), under the name
 `ISSRC_BUILD_ENV_ZIP_URL`, and the password as `ISSRC_BUILD_ENV_ZIP_PASSWORD`.
 `ISSRC_BUILD_ENV_ZIP_URL`, and the password as `ISSRC_BUILD_ENV_ZIP_PASSWORD`.
 
 
@@ -285,6 +284,11 @@ the name `ISSRC_BUILD_ENV_SYNC_TOKEN`. Finally, indicate that your fork has this
 by adding the topic `has-issrc-build-env-sync-token`. Your fork will now synchronize daily,
 by adding the topic `has-issrc-build-env-sync-token`. Your fork will now synchronize daily,
 and will automatically run the aforementioned build workflow on changes, if it's configured.
 and will automatically run the aforementioned build workflow on changes, if it's configured.
 
 
+To perform a second unattended build using a different Delphi version, add topic
+`has-issrc-build2-env` and secrets `ISSRC_BUILD2_ENV_ZIP_URL` and
+`ISSRC_BUILD2_ENV_ZIP_PASSWORD`. Unlike the main build, the second build does not produce
+any artifacts.
+
 <!-- Link references -->
 <!-- Link references -->
 [CONTRIBUTING.md]: <CONTRIBUTING.md>
 [CONTRIBUTING.md]: <CONTRIBUTING.md>
 [Projects\Bin]: <Projects/Bin>
 [Projects\Bin]: <Projects/Bin>

+ 1 - 1
build-ce.bat

@@ -87,7 +87,7 @@ if exist .\setup-presign.bat (
   echo Presign done
   echo Presign done
 )
 )
 
 
-rem  Sign using user's private key
+rem  Sign using user's private key - also see compile.bat
 call .\issig.bat sign Files\ISCmplr.dll Files\ISPP.dll Files\Setup.e32 Files\SetupLdr.e32
 call .\issig.bat sign Files\ISCmplr.dll Files\ISPP.dll Files\Setup.e32 Files\SetupLdr.e32
 if errorlevel 1 goto failed
 if errorlevel 1 goto failed
 echo ISSigTool sign done
 echo ISSigTool sign done

+ 1 - 1
build.bat

@@ -78,7 +78,7 @@ if exist .\setup-presign.bat (
   echo Presign done
   echo Presign done
 ) 
 ) 
 
 
-rem  Sign using user's private key
+rem  Sign using user's private key - also see compile.bat
 call .\issig.bat sign Files\ISCmplr.dll Files\ISPP.dll Files\Setup.e32 Files\SetupLdr.e32
 call .\issig.bat sign Files\ISCmplr.dll Files\ISPP.dll Files\Setup.e32 Files\SetupLdr.e32
 if errorlevel 1 goto failed
 if errorlevel 1 goto failed
 echo ISSigTool sign done
 echo ISSigTool sign done

+ 6 - 0
compile.bat

@@ -89,6 +89,12 @@ cd ..
 if errorlevel 1 goto failed
 if errorlevel 1 goto failed
 
 
 echo Success!
 echo Success!
+
+rem  Sign using user's private key - will be overwritten if called by build.bat
+call .\issig.bat sign Files\ISCmplr.dll Files\ISPP.dll Files\Setup.e32 Files\SetupLdr.e32
+if errorlevel 1 goto failed
+echo ISSigTool sign done
+
 goto exit
 goto exit
 
 
 :failed
 :failed

+ 3 - 2
whatsnew.htm

@@ -44,7 +44,7 @@ For conditions of distribution and use, see <a href="files/is/license.txt">LICEN
 
 
 <p><a name="6.5.0"></a><span class="ver">6.5.0-dev </span><span class="date">(?)</span></p>
 <p><a name="6.5.0"></a><span class="ver">6.5.0-dev </span><span class="date">(?)</span></p>
 <span class="head2">Improved archive extraction</span>
 <span class="head2">Improved archive extraction</span>
-<p>Support for extracting archives has been improved. It's now possible to extract password-protected archives, multi-volume archives, and multiple extra archive formats such as .zip.</p>
+<p>It's now possible to extract password-protected archives, multi-volume archives, and multiple extra archive formats such as .zip.</p>
 <p>Additionally the <tt>[Files]</tt> section now supports archive extraction. Writing Pascal Script to extract an archive is no longer necessary.</p>
 <p>Additionally the <tt>[Files]</tt> section now supports archive extraction. Writing Pascal Script to extract an archive is no longer necessary.</p>
 <p>All of this is optional and does <i>not</i> increase the size of Setup if not used.</p>
 <p>All of this is optional and does <i>not</i> increase the size of Setup if not used.</p>
 <ul>
 <ul>
@@ -88,7 +88,7 @@ For conditions of distribution and use, see <a href="files/is/license.txt">LICEN
   </li>
   </li>
 </ul>
 </ul>
 <span class="head2">Improved file downloads</span>
 <span class="head2">Improved file downloads</span>
-<p>Support for downloading files has been improved: the <tt>[Files]</tt> section now supports file downloads. Writing Pascal Script to download a file is no longer necessary and is in fact less efficient since it requires an intermediate temporary file which this new download support doesn't.</p>
+<p>The <tt>[Files]</tt> section now supports file downloads. Writing Pascal Script to download a file is no longer necessary and is in fact less efficient since it requires an intermediate temporary file which this new download support doesn't.</p>
 <ul>
 <ul>
   <li>Updated <tt>[Files]</tt> section:
   <li>Updated <tt>[Files]</tt> section:
   <ul>
   <ul>
@@ -234,6 +234,7 @@ issigtool --key-file="MyKey.ispublickey" verify "MyProg.dll"</code></pre>
       <li><i>Fix:</i> Event function <tt>CurPageChanged</tt> is now always only triggered when the current page actually changes. Before it was called twice in a row for <tt>wpPreparing</tt> when the script had a <tt>PrepareToInstall</tt> event function which returned a non empty string to instruct Setup to stop.</li>
       <li><i>Fix:</i> Event function <tt>CurPageChanged</tt> is now always only triggered when the current page actually changes. Before it was called twice in a row for <tt>wpPreparing</tt> when the script had a <tt>PrepareToInstall</tt> event function which returned a non empty string to instruct Setup to stop.</li>
     </ul>
     </ul>
   </li>
   </li>
+  <li>When available, Setup now retrieves the temporary directory path using the <tt>GetTempPath2</tt> API, which was first introduced in Windows 11 and later backported to Windows 10 and Windows Server 2016 via monthly updates. When running under the SYSTEM account, <tt>GetTempPath2</tt> returns a private directory (typically <tt>C:\Windows\SystemTemp</tt>), potentially enhancing security. On older versions of Windows or systems that haven't been updated, Setup falls back to the original <tt>GetTempPath</tt> API. (This change adds defense-in-depth; it does not address a known vulnerability.)</li>
   <li>Inno Setup 6.4.3 increased the maximum width of all task dialogs by about 50%, which helps to keep long paths from being truncated with ellipses. It now only does this if the task dialog's content actually contains a path.</li>
   <li>Inno Setup 6.4.3 increased the maximum width of all task dialogs by about 50%, which helps to keep long paths from being truncated with ellipses. It now only does this if the task dialog's content actually contains a path.</li>
   <li>All official translations which still had an UTF-8 BOM had their BOM removed. Using a BOM in UTF-8 encoded files is not needed and not recommended since Inno Setup 6.3.0.</li>
   <li>All official translations which still had an UTF-8 BOM had their BOM removed. Using a BOM in UTF-8 encoded files is not needed and not recommended since Inno Setup 6.3.0.</li>
   <li>Inno Setup is now built using Delphi 12.3 Athens instead of Delphi 12.1 Athens. Thanks to Ian Barker from Embarcadero for providing us with a license!</li>
   <li>Inno Setup is now built using Delphi 12.3 Athens instead of Delphi 12.1 Athens. Thanks to Ian Barker from Embarcadero for providing us with a license!</li>