2
0
Martijn Laan 1 жил өмнө
parent
commit
fcf5959be7

+ 1 - 26
Components/PathFunc.pas

@@ -426,33 +426,8 @@ end;
 
 function PathLowercase(const S: String): String;
 { Converts the specified path name to lowercase }
-{$IFNDEF UNICODE}
-var
-  I, L: Integer;
-{$ENDIF}
 begin
-  {$IFNDEF UNICODE}
-  if (Win32Platform <> VER_PLATFORM_WIN32_NT) and
-     (GetSystemMetrics(SM_DBCSENABLED) <> 0) then begin
-    { Japanese Windows 98's handling of double-byte Roman characters in
-      filenames is case sensitive, so we can't change the case of double-byte
-      characters. (Japanese Windows NT/2000 is case insensitive, on both FAT
-      and NTFS, in my tests.) Based on code from AnsiLowerCaseFileName. }
-    Result := S;
-    L := Length(Result);
-    I := 1;
-    while I <= L do begin
-      if Result[I] in ['A'..'Z'] then begin
-        Inc(Byte(Result[I]), 32);
-        Inc(I);
-      end
-      else
-        Inc(I, PathCharLength(Result, I));
-    end;
-  end
-  else
-  {$ENDIF}
-    Result := AnsiLowerCase(S);
+  Result := AnsiLowerCase(S);
 end;
 
 function PathPos(Ch: Char; const S: String): Integer;

+ 10 - 50
Projects/CmnFunc2.pas

@@ -18,28 +18,11 @@ interface
 uses
   Windows, SysUtils;
 
-{ Delphi 2.01's RegStr unit should never be used because it contains many
-  wrong declarations. Delphi 3's RegStr unit doesn't have this problem, but
-  for backward compatibility, it defines a few of the correct registry key
-  constants here. }
 const
-  { Do NOT localize any of these }
-  NEWREGSTR_PATH_SETUP = 'Software\Microsoft\Windows\CurrentVersion';
-  NEWREGSTR_PATH_EXPLORER = NEWREGSTR_PATH_SETUP + '\Explorer';
-  NEWREGSTR_PATH_SPECIAL_FOLDERS = NEWREGSTR_PATH_EXPLORER + '\Shell Folders';
-  NEWREGSTR_PATH_UNINSTALL = NEWREGSTR_PATH_SETUP + '\Uninstall';
-  NEWREGSTR_VAL_UNINSTALLER_DISPLAYNAME = 'DisplayName';
-  NEWREGSTR_VAL_UNINSTALLER_COMMANDLINE = 'UninstallString';
-
   KEY_WOW64_64KEY = $0100;
 
 type
-{$IFNDEF UNICODE}
-  PLeadByteSet = ^TLeadByteSet;
-  TLeadByteSet = set of AnsiChar;
-{$ENDIF}
-
-  TOneShotTimer = {$IFDEF UNICODE} record {$ELSE} object {$ENDIF}
+  TOneShotTimer = record
   private
     FLastElapsed: Cardinal;
     FStartTick: DWORD;
@@ -88,7 +71,6 @@ function StringChange(var S: String; const FromStr, ToStr: String): Integer;
 function StringChangeEx(var S: String; const FromStr, ToStr: String;
   const SupportDBCS: Boolean): Integer;
 function AdjustLength(var S: String; const Res: Cardinal): Boolean;
-function UsingWinNT: Boolean;
 function ConvertConstPercentStr(var S: String): Boolean;
 function ConvertPercentStr(var S: String): Boolean;
 function ConstPos(const Ch: Char; const S: String): Integer;
@@ -849,13 +831,6 @@ begin
   SetLength(S, Res);
 end;
 
-function UsingWinNT: Boolean;
-{ Returns True if system is running any version of Windows NT. Never returns
-  True on Windows 95 or 3.1. }
-begin
-  Result := Win32Platform = VER_PLATFORM_WIN32_NT;
-end;
-
 function InternalRegQueryStringValue(H: HKEY; Name: PChar; var ResultStr: String;
   Type1, Type2: DWORD): Boolean;
 var
@@ -1131,7 +1106,7 @@ end;
 
 function IsMemberOfGroup(const DomainAliasRid: DWORD): Boolean;
 { Returns True if the logged-on user is a member of the specified local
-  group. Always returns True on Windows 9x/Me. }
+  group. }
 const
   SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority =
     (Value: (0, 0, 0, 0, 0, 5));
@@ -1148,11 +1123,6 @@ var
   GroupInfo: PTokenGroups;
   I: Integer;
 begin
-  if Win32Platform <> VER_PLATFORM_WIN32_NT then begin
-    Result := True;
-    Exit;
-  end;
-
   Result := False;
 
   if not AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
@@ -1215,7 +1185,7 @@ end;
 
 function IsAdminLoggedOn: Boolean;
 { Returns True if the logged-on user is a member of the Administrators local
-  group. Always returns True on Windows 9x/Me. }
+  group. }
 const
   DOMAIN_ALIAS_RID_ADMINS = $00000220;
 begin
@@ -1224,7 +1194,7 @@ end;
 
 function IsPowerUserLoggedOn: Boolean;
 { Returns True if the logged-on user is a member of the Power Users local
-  group. Always returns True on Windows 9x/Me. }
+  group. }
 const
   DOMAIN_ALIAS_RID_POWER_USERS = $00000223;
 begin
@@ -1311,24 +1281,14 @@ begin
   GetUserDefaultUILanguage := GetProcAddress(GetModuleHandle(kernel32),
     'GetUserDefaultUILanguage');
   if Assigned(GetUserDefaultUILanguage) then
-    { This function is available on Windows 2000, Me, and later }
     Result := GetUserDefaultUILanguage
   else begin
-    if Win32Platform = VER_PLATFORM_WIN32_NT then begin
-      { Windows NT 4.0 }
-      if RegOpenKeyExView(rvDefault, HKEY_USERS, '.DEFAULT\Control Panel\International',
-         0, KEY_QUERY_VALUE, K) = ERROR_SUCCESS then begin
-        RegQueryStringValue(K, 'Locale', S);
-        RegCloseKey(K);
-      end;
-    end
-    else begin
-      { Windows 95/98 }
-      if RegOpenKeyExView(rvDefault, HKEY_CURRENT_USER, 'Control Panel\Desktop\ResourceLocale',
-         0, KEY_QUERY_VALUE, K) = ERROR_SUCCESS then begin
-        RegQueryStringValue(K, '', S);
-        RegCloseKey(K);
-      end;
+    { GetUserDefaultUILanguage is available on Windows 2000, Me, and later so
+      should never get here }
+    if RegOpenKeyExView(rvDefault, HKEY_USERS, '.DEFAULT\Control Panel\International',
+       0, KEY_QUERY_VALUE, K) = ERROR_SUCCESS then begin
+      RegQueryStringValue(K, 'Locale', S);
+      RegCloseKey(K);
     end;
     Val('$' + S, Result, E);
     if E <> 0 then

+ 0 - 3
Projects/CompExeUpdate.pas

@@ -396,9 +396,6 @@ var
   N: Cardinal;
   NewGroupIconDirSize: LongInt;
 begin
-  if Win32Platform <> VER_PLATFORM_WIN32_NT then
-    ResUpdateError('Only supported on Windows NT and above');
-
   Ico := nil;
 
   try

+ 0 - 4
Projects/CompMsgs.pas

@@ -191,8 +191,6 @@ const
   SCompilerDiskClusterSizeInvalid = 'DiskClusterSize must be between 1 and 32768';
   SCompilerInstallModeObsolete = 'The [%s] section directive "%s" is obsolete and ignored in this version of Inno Setup. Use command line parameters instead.';
   SCompilerMessagesFileObsolete = 'The MessagesFile directive is obsolete and no longer supported. Use the [Languages] section instead.';
-  SCompilerDirectiveIsNTOnly = 'The [%s] section directive "%s" may not be used when compiling on Windows 95/98/Me';
-  SCompilerDirectiveRequiresWindows2000 = 'The [%s] section directive "%s" may not be used when compiling on Windows 95/98/Me/NT4';
   SCompilerMustUseDisableStartupPrompt = 'DisableStartupPrompt must be set to "yes" when AppName includes constants';
   SCompilerMustNotUsePreviousLanguage = 'UsePreviousLanguage must be set to "no" when AppId includes constants';
   SCompilerMustNotUsePreviousPrivileges = 'UsePreviousPrivileges must be set to "no" when AppId includes constants and PrivilegesRequiredOverridesAllowed allows "dialog"';
@@ -353,8 +351,6 @@ const
   SCompilerFilesCantHaveNonExternalExternalSize = 'Parameter "ExternalSize" may only be used when ' +
     'the "external" flag is used';
   SCompilerFilesExcludeTooLong = 'Parameter "Excludes" contains a pattern that is too long';
-  SCompilerFilesCantReadVersionInfoOn64BitImage = 'In order for it to be able to read version info on 64-bit images, ' +
-    'the compiler must be run under Windows 2000 or later';
   SCompilerFilesUnsafeFile = 'Unsafe file detected: %s.' + SNewLine2 +
     'See the "Unsafe Files" topic in the help file for more information';
   SCompilerFilesSystemDirUsed = 'Attempt to deploy DLL file from own Windows System directory.' + SNewLine2 +

+ 0 - 47
Projects/Compile.pas

@@ -713,41 +713,6 @@ begin
   F.Seek(0);
 end;
 
-function Is64BitPEImage(const Filename: String): Boolean;
-{ Returns True if the specified file is a non-32-bit PE image, False
-  otherwise. }
-var
-  F: TFile;
-  DosHeader: packed record
-    Sig: array[0..1] of AnsiChar;
-    Other: array[0..57] of Byte;
-    PEHeaderOffset: LongWord;
-  end;
-  PESigAndHeader: packed record
-    Sig: DWORD;
-    Header: TImageFileHeader;
-    OptHeaderMagic: Word;
-  end;
-begin
-  Result := False;
-  F := TFile.Create(Filename, fdOpenExisting, faRead, fsRead);
-  try
-    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(PESigAndHeader, SizeOf(PESigAndHeader)) = SizeOf(PESigAndHeader) then begin
-          if (PESigAndHeader.Sig = IMAGE_NT_SIGNATURE) and
-             (PESigAndHeader.OptHeaderMagic <> IMAGE_NT_OPTIONAL_HDR32_MAGIC) then
-            Result := True;
-        end;
-      end;
-    end;
-  finally
-    F.Free;
-  end;
-end;
-
 function CountChars(const S: String; C: Char): Integer;
 var
   I: Integer;
@@ -3920,10 +3885,6 @@ begin
           CompressProps.WorkerProcessFilename := GetLZMAExeFilename(True)
         else
           CompressProps.WorkerProcessFilename := '';
-        if (CompressProps.WorkerProcessFilename <> '') and
-           (Byte(GetVersion()) < 5) then
-          AbortCompileOnLineFmt(SCompilerDirectiveRequiresWindows2000,
-            ['Setup', KeyName]);
       end;
     ssMergeDuplicateFiles: begin
         DontMergeDuplicateFiles := not StrToBool(Value);
@@ -3999,8 +3960,6 @@ begin
         SetSetupHeaderOption(shRestartIfNeededByRun);
       end;
     ssSetupIconFile: begin
-        if (Value <> '') and (Win32Platform <> VER_PLATFORM_WIN32_NT) then
-          AbortCompileOnLineFmt(SCompilerDirectiveIsNTOnly, ['Setup', KeyName]);
         SetupIconFilename := Value;
       end;
     ssSetupLogging: begin
@@ -6002,12 +5961,6 @@ type
       if not ExternalFile and not(foIgnoreVersion in NewFileEntry^.Options) and
          (NewFileLocationEntry^.Flags * [foVersionInfoValid, foVersionInfoNotValid] = []) then begin
         AddStatus(Format(SCompilerStatusFilesVerInfo, [SourceFile]));
-        { Windows versions prior to 2000 cannot read version info on 64-bit
-          images. Throw an error rather than silently failing to read the
-          version info (which could be dangerous). }
-        if (Win32Platform <> VER_PLATFORM_WIN32_NT) or (Byte(GetVersion) < 5) then
-          if Is64BitPEImage(SourceFile) then
-            AbortCompileOnLine(SCompilerFilesCantReadVersionInfoOn64BitImage);
         if GetVersionNumbers(SourceFile, VersionNumbers) then begin
           NewFileLocationEntry^.FileVersionMS := VersionNumbers.MS;
           NewFileLocationEntry^.FileVersionLS := VersionNumbers.LS;

+ 0 - 14
Projects/DebugStruct.pas

@@ -140,29 +140,15 @@ end;
 function SendCopyDataMessageStr(DestWnd, SourceWnd: HWND; CopyDataMsg: DWORD;
   Data: AnsiString): LRESULT;
 begin
-  { Windows 95/98/Me bug workaround: Call UniqueString to ensure the string is
-    in writable memory. Amazingly enough, sending a WM_COPYDATA message with a
-    read-only buffer causes a fatal page fault error. }
-  if (Win32Platform = VER_PLATFORM_WIN32_WINDOWS) and
-     IsBadWritePtr(Pointer(Data), Length(Data)*SizeOf(Data[1])) then
-    UniqueString(Data);
   Result := SendCopyDataMessage(DestWnd, SourceWnd, CopyDataMsg,
     Pointer(Data), Length(Data)*SizeOf(Data[1]));
 end;
 
-{$IFDEF UNICODE}
 function SendCopyDataMessageStr(DestWnd, SourceWnd: HWND; CopyDataMsg: DWORD;
   Data: UnicodeString): LRESULT;
 begin
-  { Windows 95/98/Me bug workaround: Call UniqueString to ensure the string is
-    in writable memory. Amazingly enough, sending a WM_COPYDATA message with a
-    read-only buffer causes a fatal page fault error. }
-  if (Win32Platform = VER_PLATFORM_WIN32_WINDOWS) and
-     IsBadWritePtr(Pointer(Data), Length(Data)*SizeOf(Data[1])) then
-    UniqueString(Data);
   Result := SendCopyDataMessage(DestWnd, SourceWnd, CopyDataMsg,
     Pointer(Data), Length(Data)*SizeOf(Data[1]));
 end;
-{$ENDIF}
 
 end.

+ 2 - 4
Projects/FileClass.pas

@@ -684,16 +684,14 @@ begin
      (Cardinal(EExternalException(E).ExceptionRecord.NumberParameters) >= Cardinal(2)) and
      (Cardinal(EExternalException(E).ExceptionRecord.ExceptionInformation[1]) >= Cardinal(FMemory)) and
      (Cardinal(EExternalException(E).ExceptionRecord.ExceptionInformation[1]) < Cardinal(Cardinal(FMemory) + FMapSize)) then begin
-    { NT has a third parameter containing the NT status code of the error
+    { They should be a third parameter containing the NT status code of the error
       condition that caused the exception. Convert that into a Win32 error code
       and use it to generate our error message. }
     if (Cardinal(EExternalException(E).ExceptionRecord.NumberParameters) >= Cardinal(3)) and
        Assigned(_RtlNtStatusToDosError) then
       TFile.RaiseError(_RtlNtStatusToDosError(EExternalException(E).ExceptionRecord.ExceptionInformation[2]))
     else begin
-      { Windows 9x/Me doesn't have a third parameter, and 95 doesn't have
-        RtlNtStatusToDosError, so use generic "The system cannot [read|write]
-        to the specified device" errors }
+      { Use generic "The system cannot [read|write] to the specified device" errors }
       if EExternalException(E).ExceptionRecord.ExceptionInformation[0] = 0 then
         TFile.RaiseError(ERROR_READ_FAULT)
       else

+ 2 - 2
Projects/ISPP/IsppSessions.pas

@@ -3,7 +3,7 @@
   Copyright (C) 2001-2002 Alex Yackimoff
 
   Inno Setup
-  Copyright (C) 1997-2020 Jordan Russell
+  Copyright (C) 1997-2024 Jordan Russell
   Portions by Martijn Laan
   For conditions of distribution and use, see LICENSE.TXT.
 }
@@ -25,7 +25,7 @@ implementation
 
 {$I ..\Version.inc}
 
-uses SysUtils, Classes, IsppStack {$IFDEF IS_D12}, Windows{$ENDIF};
+uses SysUtils, Classes, IsppStack, Windows;
 
 procedure WarningMsg(const Msg: string; const Args: array of const);
 var

+ 1 - 4
Projects/InstFnc2.pas

@@ -82,15 +82,12 @@ begin
   Result := '';
   CurFilename := nil;
   OleResult := PF.GetCurFile(CurFilename);
-  { Note: Prior to Windows 2000/Me, GetCurFile succeeds but returns a NULL
-    pointer }
   if SUCCEEDED(OleResult) and Assigned(CurFilename) then begin
     if OleResult = S_OK then
       Result := WideCharToString(CurFilename);
     CoTaskMemFree(CurFilename);
   end;
-  { If GetCurFile didn't work (e.g. not running Windows 2000/Me or later), we
-    have no choice but to try to guess the filename }
+  { If GetCurFile didn't work, we have no choice but to try to guess the filename }
   if Result = '' then begin
     if NewFileExists(OriginalFilename) then
       Result := OriginalFilename

+ 85 - 266
Projects/InstFunc.pas

@@ -122,7 +122,8 @@ function ForceDirectories(const DisableFsRedir: Boolean; Dir: String): Boolean;
 implementation
 
 uses
-  Messages, ShellApi, PathFunc, Msgs, MsgIDs, FileClass, RedirFunc, SetupTypes, Hash, Classes;
+  Messages, ShellApi, PathFunc, Msgs, MsgIDs, FileClass, RedirFunc, SetupTypes,
+  Hash, Classes, RegStr;
 
 procedure InternalError(const Id: String);
 begin
@@ -383,93 +384,23 @@ end;
 procedure RestartReplace(const DisableFsRedir: Boolean; TempFile, DestFile: String);
 { Renames TempFile to DestFile the next time Windows is started. If DestFile
   already existed, it will be overwritten. If DestFile is '' then TempFile
-  will be deleted, however this is only supported by 95/98 and NT, not
-  Windows 3.1x. }
-var
-  WinDir, WinInitFile, TempWinInitFile: String;
-  OldF: TTextFileReader;
-  NewF: TTextFileWriter;
-  L, L2: String;
-  RenameSectionFound, WriteLastLine: Boolean;
+  will be deleted.. }
 begin
   TempFile := PathExpand(TempFile);
   if DestFile <> '' then
     DestFile := PathExpand(DestFile);
 
-  if not UsingWinNT then begin
-    { Because WININIT.INI allows multiple entries with the same name,
-      it must manually parse the file instead of using
-      WritePrivateProfileString }
-    WinDir := GetWinDir;
-    WinInitFile := AddBackslash(WinDir) + 'WININIT.INI';
-    TempWinInitFile := GenerateUniqueName(False, WinDir, '.tmp');
-    try
-      OldF := nil;
-      NewF := nil;
-      try
-        { Flush Windows' cache for the file first }
-        WritePrivateProfileString(nil, nil, nil, PChar(WinInitFile));
-        OldF := TTextFileReader.Create(WinInitFile, fdOpenAlways, faRead,
-          fsRead);
-        NewF := TTextFileWriter.Create(TempWinInitFile, fdCreateAlways,
-          faWrite, fsNone);
-        RenameSectionFound := False;
-        WriteLastLine := False;
-        while not OldF.Eof do begin
-          L := OldF.ReadLine;
-          WriteLastLine := True;
-          L2 := Trim(L);
-          if (L2 <> '') and (L2[1] = '[') then begin
-            if CompareText(L2, '[rename]') = 0 then
-              RenameSectionFound := True
-            else
-            if RenameSectionFound then
-              Break;
-          end;
-          NewF.WriteLine(L);
-          WriteLastLine := False;
-        end;
-        if not RenameSectionFound then
-          NewF.WriteLine('[rename]');
-        if DestFile <> '' then
-          L2 := GetShortName(DestFile)
-        else
-          L2 := 'NUL';
-        NewF.WriteLine(L2 + '=' + GetShortName(TempFile));
-        if WriteLastLine then
-          NewF.WriteLine(L);
-        while not OldF.Eof do begin
-          L := OldF.ReadLine;
-          NewF.WriteLine(L);
-        end;
-      finally
-        NewF.Free;
-        OldF.Free;
-      end;
-      { Strip any read-only attribute }
-      SetFileAttributes(PChar(WinInitFile), FILE_ATTRIBUTE_ARCHIVE);
-      if not DeleteFile(WinInitFile) then
-        Win32ErrorMsg('DeleteFile');
-      if not MoveFile(PChar(TempWinInitFile), PChar(WinInitFile)) then
-        Win32ErrorMsg('MoveFile');
-    except
-      DeleteFile(TempWinInitFile);
-      raise;
-    end;
-  end
-  else begin
-    if not DisableFsRedir then begin
-      { Work around WOW64 bug present in the IA64 and x64 editions of Windows
-        XP (3790) and Server 2003 prior to SP1 RC2: MoveFileEx writes filenames
-        to the registry verbatim without mapping system32->syswow64. }
-      TempFile := ReplaceSystemDirWithSysWow64(TempFile);
-      if DestFile <> '' then
-        DestFile := ReplaceSystemDirWithSysWow64(DestFile);
-    end;
-    if not MoveFileExRedir(DisableFsRedir, TempFile, DestFile,
-       MOVEFILE_DELAY_UNTIL_REBOOT or MOVEFILE_REPLACE_EXISTING) then
-      Win32ErrorMsg('MoveFileEx');
+  if not DisableFsRedir then begin
+    { Work around WOW64 bug present in the IA64 and x64 editions of Windows
+      XP (3790) and Server 2003 prior to SP1 RC2: MoveFileEx writes filenames
+      to the registry verbatim without mapping system32->syswow64. }
+    TempFile := ReplaceSystemDirWithSysWow64(TempFile);
+    if DestFile <> '' then
+      DestFile := ReplaceSystemDirWithSysWow64(DestFile);
   end;
+  if not MoveFileExRedir(DisableFsRedir, TempFile, DestFile,
+     MOVEFILE_DELAY_UNTIL_REBOOT or MOVEFILE_REPLACE_EXISTING) then
+    Win32ErrorMsg('MoveFileEx');
 end;
 
 function DelTree(const DisableFsRedir: Boolean; const Path: String;
@@ -592,7 +523,7 @@ end;
 procedure IncrementSharedCount(const RegView: TRegView; const Filename: String;
   const AlreadyExisted: Boolean);
 const
-  SharedDLLsKey = NEWREGSTR_PATH_SETUP + '\SharedDLLs';  {don't localize}
+  SharedDLLsKey = REGSTR_PATH_SETUP + '\SharedDLLs';  {don't localize}
 var
   ErrorCode: Longint;
   K: HKEY;
@@ -655,7 +586,7 @@ function DecrementSharedCount(const RegView: TRegView;
 { Attempts to decrement the shared file reference count of Filename. Returns
   True if the count reached zero (meaning it's OK to delete the file). }
 const
-  SharedDLLsKey = NEWREGSTR_PATH_SETUP + '\SharedDLLs';  {don't localize}
+  SharedDLLsKey = REGSTR_PATH_SETUP + '\SharedDLLs';  {don't localize}
 var
   ErrorCode: Longint;
   K: HKEY;
@@ -874,9 +805,6 @@ function IsProtectedSystemFile(const DisableFsRedir: Boolean;
 var
   M: HMODULE;
   FN: String;
-{$IFNDEF UNICODE}
-  Buf: array[0..4095] of WideChar;
-{$ENDIF}
 begin
   if not SFCInitialized then begin
     M := SafeLoadLibrary(PChar(AddBackslash(GetSystemDir) + 'sfc.dll'),
@@ -892,18 +820,10 @@ begin
     FN := PathExpand(Filename);
     if not DisableFsRedir then
       FN := ReplaceSystemDirWithSysWow64(FN);
-{$IFDEF UNICODE}
     Result := SfcIsFileProtectedFunc(0, PChar(FN));
-{$ELSE}
-    Buf[MultiByteToWideChar(CP_ACP, 0, PChar(FN), Length(FN), Buf,
-      (SizeOf(Buf) div SizeOf(Buf[0])) - 1)] := #0;
-    Result := (Buf[0] <> #0) and SfcIsFileProtectedFunc(0, Buf);
-{$ENDIF}
   end
-  else begin
-    { Windows File Protection doesn't exist on Windows 95/98/NT4 }
-    Result := False;
-  end;
+  else
+    Result := False; { Should never happen }
 end;
 
 procedure HandleProcessWait(ProcessHandle: THandle; const Wait: TExecWait;
@@ -959,16 +879,13 @@ begin
           Filename: "c:\batch.bat"; Parameters: """abc"""
         And other Windows versions might have unknown quirks too, since
         CreateProcess isn't documented to accept .bat files in the first place. }
-      if UsingWinNT then
-        { With cmd.exe, the whole command line must be quoted for quoted
-          parameters to work. For example, this fails:
-            cmd.exe /c "z:\blah.bat" "test"
-          But this works:
-            cmd.exe /c ""z:\blah.bat" "test""
-        }
-        CmdLine := '"' + AddBackslash(GetSystemDir) + 'cmd.exe" /C "' + CmdLine + '"'
-      else
-        CmdLine := '"' + AddBackslash(GetWinDir) + 'COMMAND.COM" /C ' + CmdLine;
+      { With cmd.exe, the whole command line must be quoted for quoted
+        parameters to work. For example, this fails:
+          cmd.exe /c "z:\blah.bat" "test"
+        But this works:
+          cmd.exe /c ""z:\blah.bat" "test""
+      }
+      CmdLine := '"' + AddBackslash(GetSystemDir) + 'cmd.exe" /C "' + CmdLine + '"'
     end;
     if WorkingDir = '' then
       WorkingDir := PathExtractDir(Filename);
@@ -1140,44 +1057,35 @@ function NewAdjustTokenPrivileges(TokenHandle: THandle; DisableAllPrivileges: BO
   external advapi32 name 'AdjustTokenPrivileges';
 
 function RestartComputer: Boolean;
-{ Restarts the computer. On Windows 9x/Me, the function will NOT return if it
-  is successful. }
+{ Restarts the computer. }
 var
   Token: THandle;
   TokenPriv: TTokenPrivileges;
 const
   SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';  { don't localize }
 begin
-  if Win32Platform = VER_PLATFORM_WIN32_NT then begin
-    if not OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,
-       {$IFNDEF Delphi3orHigher} @Token {$ELSE} Token {$ENDIF}) then begin
-      Result := False;
-      Exit;
-    end;
+  if not OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,
+     Token) then begin
+    Result := False;
+    Exit;
+  end;
 
-    LookupPrivilegeValue(nil, SE_SHUTDOWN_NAME, TokenPriv.Privileges[0].Luid);
+  LookupPrivilegeValue(nil, SE_SHUTDOWN_NAME, TokenPriv.Privileges[0].Luid);
 
-    TokenPriv.PrivilegeCount := 1;
-    TokenPriv.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
+  TokenPriv.PrivilegeCount := 1;
+  TokenPriv.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
 
-    NewAdjustTokenPrivileges(Token, False, TokenPriv, 0, nil, nil);
+  NewAdjustTokenPrivileges(Token, False, TokenPriv, 0, nil, nil);
 
-    { Cannot test the return value of AdjustTokenPrivileges. }
-    if GetLastError <> ERROR_SUCCESS then begin
-      Result := False;
-      Exit;
-    end;
+  { Cannot test the return value of AdjustTokenPrivileges. }
+  if GetLastError <> ERROR_SUCCESS then begin
+    Result := False;
+    Exit;
   end;
 
   Result := ExitWindowsEx(EWX_REBOOT, 0);
 
-  { On Windows 9x/Me:
-    ExitWindowsEx synchronously sends WM_QUERYENDSESSION messages to all
-    processes except the current process. If any WM_QUERYENDSESSION handler
-    blocks the shutdown, it returns False. Otherwise, it kills the current
-    process and does not return.
-    On NT platforms:
-    ExitWindowsEx returns True immediately. The system then asynchronously
+  { ExitWindowsEx returns True immediately. The system then asynchronously
     sends WM_QUERYENDSESSION messages to all processes, including the current
     process. The current process is not killed until it has received
     WM_QUERYENDSESSION and WM_ENDSESSION messages. }
@@ -1205,48 +1113,24 @@ end;
 
 function MakePendingFileRenameOperationsChecksum: TMD5Digest;
 { Calculates a checksum of the current PendingFileRenameOperations registry
-  value (on NT 4+ platforms) or of the current WININIT.INI file (on non-NT
-  platforms). The caller can use this checksum to determine if
-  PendingFileRenameOperations or WININIT.INI was changed (perhaps by another
-  program). }
+  value The caller can use this checksum to determine if
+  PendingFileRenameOperations was changed (perhaps by another program). }
 var
   Context: TMD5Context;
   K: HKEY;
   S: String;
-  WinInitFile: String;
-  F: TFile;
-  Buf: array[0..4095] of Byte;
-  BytesRead: Cardinal;
 begin
   MD5Init(Context);
   try
-    if UsingWinNT then begin
-      if RegOpenKeyExView(rvDefault, HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager',
-         0, KEY_QUERY_VALUE, K) = ERROR_SUCCESS then begin
-        if RegQueryMultiStringValue(K, 'PendingFileRenameOperations', S) then
-          MD5Update(Context, S[1], Length(S)*SizeOf(S[1]));
-        { When "PendingFileRenameOperations" is full, it spills over into
-          "PendingFileRenameOperations2" }
-        if RegQueryMultiStringValue(K, 'PendingFileRenameOperations2', S) then
-          MD5Update(Context, S[1], Length(S)*SizeOf(S[1]));
-        RegCloseKey(K);
-      end;
-    end
-    else begin
-      WinInitFile := AddBackslash(GetWinDir) + 'WININIT.INI';
-      if NewFileExists(WinInitFile) then begin
-        F := TFile.Create(WinInitFile, fdOpenExisting, faRead, fsRead);
-        try
-          while True do begin
-            BytesRead := F.Read(Buf, SizeOf(Buf));
-            if BytesRead = 0 then
-              Break;
-            MD5Update(Context, Buf, BytesRead);
-          end;
-        finally
-          F.Free;
-        end;
-      end;
+    if RegOpenKeyExView(rvDefault, HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager',
+       0, KEY_QUERY_VALUE, K) = ERROR_SUCCESS then begin
+      if RegQueryMultiStringValue(K, 'PendingFileRenameOperations', S) then
+        MD5Update(Context, S[1], Length(S)*SizeOf(S[1]));
+      { When "PendingFileRenameOperations" is full, it spills over into
+        "PendingFileRenameOperations2" }
+      if RegQueryMultiStringValue(K, 'PendingFileRenameOperations2', S) then
+        MD5Update(Context, S[1], Length(S)*SizeOf(S[1]));
+      RegCloseKey(K);
     end;
   except
     { don't propagate exceptions }
@@ -1260,101 +1144,46 @@ procedure EnumFileReplaceOperationsFilenames(const EnumFunc: TEnumFROFilenamesPr
   registry value or WININIT.INI file. The function does not distinguish between
   source and destination filenames; it enumerates both. }
 
-  procedure DoNT;
-
-    procedure DoValue(const K: HKEY; const ValueName: PChar);
-    var
-      S: String;
-      P, PEnd: PChar;
-    begin
-      if not RegQueryMultiStringValue(K, ValueName, S) then
-        Exit;
-      P := PChar(S);
-      PEnd := P + Length(S);
-      while P < PEnd do begin
-        if P[0] = '!' then
-          { Note: '!' means that MoveFileEx was called with the
-            MOVEFILE_REPLACE_EXISTING flag }
-          Inc(P);
-        if StrLComp(P, '\??\', 4) = 0 then begin
-          Inc(P, 4);
-          if P[0] <> #0 then
-            EnumFunc(P, Param);
-        end;
-        Inc(P, StrLen(P) + 1);
-      end;
-    end;
-
+  procedure DoValue(const K: HKEY; const ValueName: PChar);
   var
-    K: HKEY;
+    S: String;
+    P, PEnd: PChar;
   begin
-    if RegOpenKeyExView(rvDefault, HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager',
-       0, KEY_QUERY_VALUE, K) = ERROR_SUCCESS then begin
-      try
-        DoValue(K, 'PendingFileRenameOperations');
-        { When "PendingFileRenameOperations" is full, it spills over into
-          "PendingFileRenameOperations2" }
-        DoValue(K, 'PendingFileRenameOperations2');
-      finally
-        RegCloseKey(K);
+    if not RegQueryMultiStringValue(K, ValueName, S) then
+      Exit;
+    P := PChar(S);
+    PEnd := P + Length(S);
+    while P < PEnd do begin
+      if P[0] = '!' then
+        { Note: '!' means that MoveFileEx was called with the
+          MOVEFILE_REPLACE_EXISTING flag }
+        Inc(P);
+      if StrLComp(P, '\??\', 4) = 0 then begin
+        Inc(P, 4);
+        if P[0] <> #0 then
+          EnumFunc(P, Param);
       end;
+      Inc(P, StrLen(P) + 1);
     end;
   end;
 
-  procedure DoNonNT;
-  var
-    WinInitFile: String;
-    F: TTextFileReader;
-    Line, Filename: String;
-    InRenameSection: Boolean;
-    P: Integer;
-  begin
-    WinInitFile := AddBackslash(GetWinDir) + 'WININIT.INI';
-    if not NewFileExists(WinInitFile) then
-      Exit;
+var
+  K: HKEY;
+begin
+  if RegOpenKeyExView(rvDefault, HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager',
+     0, KEY_QUERY_VALUE, K) = ERROR_SUCCESS then begin
     try
-      F := TTextFileReader.Create(WinInitFile, fdOpenExisting, faRead, fsRead);
-      try
-        InRenameSection := False;
-        while not F.Eof do begin
-          Line := Trim(F.ReadLine);
-          if (Line = '') or (Line[1] = ';') then
-            Continue;
-          if Line[1] = '[' then begin
-            InRenameSection := (CompareText(Line, '[rename]') = 0);
-          end
-          else if InRenameSection then begin
-            P := Pos('=', Line);
-            if P > 0 then begin
-              Filename := Copy(Line, 1, P-1);
-              if (Filename <> '') and (CompareText(Filename, 'NUL') <> 0) then
-                EnumFunc(Filename, Param);
-              Filename := Copy(Line, P+1, Maxint);
-              if (Filename <> '') and (CompareText(Filename, 'NUL') <> 0) then
-                EnumFunc(Filename, Param);
-            end;
-          end;
-        end;
-      finally
-        F.Free;
-      end;
-    except
-      { ignore exceptions }
+      DoValue(K, 'PendingFileRenameOperations');
+      { When "PendingFileRenameOperations" is full, it spills over into
+        "PendingFileRenameOperations2" }
+      DoValue(K, 'PendingFileRenameOperations2');
+    finally
+      RegCloseKey(K);
     end;
   end;
-
-begin
-  if UsingWinNT then
-    DoNT
-  else
-    DoNonNT;
 end;
 
 procedure UnregisterFont(const FontName, FontFilename: String; const PerUserFont: Boolean);
-const
-  FontsKeys: array[Boolean] of PChar =
-    (NEWREGSTR_PATH_SETUP + '\Fonts',
-     'Software\Microsoft\Windows NT\CurrentVersion\Fonts');
 var
   RootKey, K: HKEY;
 begin
@@ -1363,7 +1192,7 @@ begin
   else
     RootKey := HKEY_LOCAL_MACHINE;
 
-  if RegOpenKeyExView(rvDefault, RootKey, FontsKeys[UsingWinNT],
+  if RegOpenKeyExView(rvDefault, RootKey, 'Software\Microsoft\Windows NT\CurrentVersion\Fonts',
      0, KEY_SET_VALUE, K) = ERROR_SUCCESS then begin
     RegDeleteValue(K, PChar(FontName));
     RegCloseKey(K);
@@ -1387,7 +1216,7 @@ begin
     GetDiskFreeSpaceEx, however, *does* succeed with UNC paths, so use it
     if available. }
   GetDiskFreeSpaceExFunc := GetProcAddress(GetModuleHandle(kernel32),
-    {$IFDEF UNICODE}'GetDiskFreeSpaceExW'{$ELSE}'GetDiskFreeSpaceExA'{$ENDIF});
+    'GetDiskFreeSpaceExW');
   if not DisableFsRedirectionIf(DisableFsRedir, PrevState) then begin
     Result := False;
     Exit;
@@ -1402,9 +1231,8 @@ begin
         DWORD(SectorsPerCluster), DWORD(BytesPerSector), DWORD(FreeClusters),
         DWORD(TotalClusters));
       if Result then begin
-        { Windows 95/98 cap the result of GetDiskFreeSpace at 2GB, but NT 4.0
-          does not, so we must use a 64-bit multiply operation to avoid an
-          overflow. }
+        { The result of GetDiskFreeSpace does not cap at 2GB, so we must use a
+          64-bit multiply operation to avoid an overflow. }
         Multiply32x32to64(BytesPerSector * SectorsPerCluster, FreeClusters,
           FreeBytes);
         Multiply32x32to64(BytesPerSector * SectorsPerCluster, TotalClusters,
@@ -1531,14 +1359,9 @@ begin
     I := 0;
     while GetLanguageEntryProc(I, LangEntry) do begin
       if LangEntry.LanguageID = UILang then begin
-{$IFNDEF UNICODE}
-        if (LangEntry.LanguageCodePage = 0) or (LangEntry.LanguageCodePage = GetACP) then
-{$ENDIF}
-        begin
-          ResultIndex := I;
-          Result := ddMatch;
-          Exit;
-        end;
+        ResultIndex := I;
+        Result := ddMatch;
+        Exit;
       end;
       Inc(I);
     end;
@@ -1546,9 +1369,6 @@ begin
     I := 0;
     while GetLanguageEntryProc(I, LangEntry) do begin
       if (LangEntry.LanguageID and $3FF) = (UILang and $3FF) then begin
-{$IFNDEF UNICODE}
-        if (LangEntry.LanguageCodePage = 0) or (LangEntry.LanguageCodePage = GetACP) then
-{$ELSE}
         { On Unicode, there is no LanguageCodePage filter, so we have to check
           the language IDs to ensure we don't return Simplified Chinese on a
           Traditional Chinese system, or vice versa.
@@ -1558,7 +1378,6 @@ begin
           Traditional Chinese LANGIDs ($0404, $0C04, $1404) use CP 950 }
         if ((UILang and $3FF) <> LANG_CHINESE) or
            (GetCodePageFromLangID(LangEntry.LanguageID) = GetCodePageFromLangID(UILang)) then
-{$ENDIF}
         begin
           ResultIndex := I;
           Result := ddMatch;

+ 17 - 35
Projects/Install.pas

@@ -35,7 +35,7 @@ uses
   Compress, SHA1, PathFunc, CmnFunc, CmnFunc2, RedirFunc, Int64Em, MsgIDs,
   Wizard, DebugStruct, DebugClient, VerInfo, ScriptRunner, RegDLL, Helper,
   ResUpdate, DotNet, TaskbarProgressFunc, NewProgressBar, RestartManager,
-  Net.HTTPClient, Net.URLClient, NetEncoding;
+  Net.HTTPClient, Net.URLClient, NetEncoding, RegStr;
 
 type
   TSetupUninstallLog = class(TUninstallLog)
@@ -683,13 +683,9 @@ var
       else
         Z := ExpandedAppVerName;
       HandleDuplicateDisplayNames(Z);
-      { For the entry to appear in ARP, DisplayName cannot exceed 63 characters
-        on Windows 9x/NT 4.0, or 259 characters on Windows 2000 and later. }
-      if WindowsVersionAtLeast(5, 0) then
-        I := 259
-      else
-        I := 63;
-      SetStringValue(H2, 'DisplayName', Copy(Z, 1, I));
+      { For the entry to appear in ARP, DisplayName cannot exceed 259 characters
+        on Windows 2000 and later. }
+      SetStringValue(H2, 'DisplayName', Copy(Z, 1, 259));
       SetStringValueUnlessEmpty(H2, 'DisplayIcon', ExpandConst(SetupHeader.UninstallDisplayIcon));
       var ExtraUninstallString: String;
       if shUninstallLogging in SetupHeader.Options then
@@ -926,10 +922,6 @@ var
 
     procedure InstallFont(const Filename, FontName: String;
       const PerUserFont, AddToFontTableNow: Boolean; var WarnedPerUserFonts: Boolean);
-    const
-      FontsKeys: array[Boolean] of PChar =
-        (NEWREGSTR_PATH_SETUP + '\Fonts',
-         'Software\Microsoft\Windows NT\CurrentVersion\Fonts');
     var
       RootKey, K: HKEY;
     begin
@@ -952,7 +944,7 @@ var
           RootKey := HKEY_CURRENT_USER
         else
           RootKey := HKEY_LOCAL_MACHINE;
-        if RegOpenKeyExView(rvDefault, RootKey, FontsKeys[IsNT], 0,
+        if RegOpenKeyExView(rvDefault, RootKey, 'Software\Microsoft\Windows NT\CurrentVersion\Fonts', 0,
            KEY_SET_VALUE, K) = ERROR_SUCCESS then begin
           if RegSetValueEx(K, PChar(FontName), 0, REG_SZ, PChar(Filename),
              (Length(Filename)+1)*SizeOf(Filename[1])) <> ERROR_SUCCESS then
@@ -1179,19 +1171,12 @@ var
             Log('Non-default bitness: 32-bit');
         end;
 
-        { See if it's a protected system file.
-          Note: We don't call IsProtectedSystemFile anymore on Windows Me
-          even though it supports WFP. Two users reported that installs ran
-          very slowly on 4.2.1, and with the help of one of the users, the
-          cause was narrowed down to this call. For him, it was taking 6
-          seconds per call. I have no idea what would cause it to be so
-          slow; it only took a few milliseconds in my tests on Windows Me. }
-        IsProtectedFile := False;
-        if IsNT and (WindowsVersion >= Cardinal($05000000)) then
-          if IsProtectedSystemFile(DisableFsRedir, DestFile) then begin
-            Log('Dest file is protected by Windows File Protection.');
-            IsProtectedFile := (CurFile^.FileType = ftUserFile);
-          end;
+        { See if it's a protected system file.  }
+        if IsProtectedSystemFile(DisableFsRedir, DestFile) then begin
+          Log('Dest file is protected by Windows File Protection.');
+          IsProtectedFile := (CurFile^.FileType = ftUserFile);
+        end else
+          IsProtectedFile := False;
 
         DestFileExists := NewFileExistsRedir(DisableFsRedir, DestFile);
         if not CheckedDestFileExistedBefore then begin
@@ -2100,14 +2085,12 @@ var
     end;
 
     function ExpandAppPath(const Filename: String): String;
-    const
-      AppPathsBaseKey = NEWREGSTR_PATH_SETUP + '\App Paths\';
     var
       K: HKEY;
       Found: Boolean;
     begin
       if RegOpenKeyExView(InstallDefaultRegView, HKEY_LOCAL_MACHINE,
-         PChar(AppPathsBaseKey + Filename), 0, KEY_QUERY_VALUE, K) = ERROR_SUCCESS then begin
+         PChar(REGSTR_PATH_APPPATHS + '\' + Filename), 0, KEY_QUERY_VALUE, K) = ERROR_SUCCESS then begin
         Found := RegQueryStringValue(K, '', Result);
         RegCloseKey(K);
         if Found then
@@ -2585,7 +2568,6 @@ var
 
     const
       Chars: array[Boolean, Boolean] of Char = (('s', 't'), ('S', 'T'));
-      RunOnceKey = NEWREGSTR_PATH_SETUP + '\RunOnce';
     var
       RegSvrExeFilename: String;
       F: TTextFileWriter;
@@ -2605,8 +2587,8 @@ var
           { In case Windows directory is write protected, try the Temp directory.
             Windows directory is our first choice since some people (ignorantly)
             put things like "DELTREE C:\WINDOWS\TEMP\*.*" in their AUTOEXEC.BAT.
-            Also on Windows 2000 and later, each user has his own personal Temp
-            directory which may not be accessible by other users. }
+            Also, each user has his own personal Temp directory which may not
+            be accessible by other users. }
           RegSvrExeFilename := CreateRegSvrExe(GetTempDir);
         end;
       end
@@ -2644,11 +2626,11 @@ var
           RootKey := HKEY_LOCAL_MACHINE
         else
           RootKey := HKEY_CURRENT_USER;
-        ErrorCode := RegCreateKeyExView(rvDefault, RootKey, RunOnceKey, 0, nil,
+        ErrorCode := RegCreateKeyExView(rvDefault, RootKey, REGSTR_PATH_RUNONCE, 0, nil,
           REG_OPTION_NON_VOLATILE, KEY_SET_VALUE or KEY_QUERY_VALUE,
           nil, H, @Disp);
         if ErrorCode <> ERROR_SUCCESS then
-          RegError(reRegCreateKeyEx, RootKey, RunOnceKey, ErrorCode);
+          RegError(reRegCreateKeyEx, RootKey, REGSTR_PATH_RUNONCE, ErrorCode);
         try
           J := 0;
           while True do begin
@@ -2666,7 +2648,7 @@ var
               ErrorCode := RegSetValueEx(H, PChar(ValueName), 0, REG_SZ, PChar(Data),
                 (Length(Data)+1)*SizeOf(Data[1]));
               if ErrorCode <> ERROR_SUCCESS then
-                RegError(reRegSetValueEx, RootKey, RunOnceKey, ErrorCode);
+                RegError(reRegSetValueEx, RootKey, REGSTR_PATH_RUNONCE, ErrorCode);
               Break;
             end;
           end;

+ 2 - 6
Projects/LZMA.pas

@@ -2,7 +2,7 @@ unit LZMA;
 
 {
   Inno Setup
-  Copyright (C) 1997-2010 Jordan Russell
+  Copyright (C) 1997-2024 Jordan Russell
   Portions by Martijn Laan
   For conditions of distribution and use, see LICENSE.TXT.
 
@@ -15,12 +15,8 @@ interface
 {$I VERSION.INC}
 
 uses
-  Windows, SysUtils, {$IFNDEF Delphi3orHigher} Ole2, {$ENDIF}
+  Windows, SysUtils,
   Compress, Int64Em;
-  { Note: Ole2 must be included in the 'uses' clause on D2, and after Windows,
-    because it redefines E_* constants in Windows that are incorrect.
-    E_OUTOFMEMORY, for example, is defined as $80000002 in Windows, instead
-    of $8007000E. }
 
 function LZMAInitCompressFunctions(Module: HMODULE): Boolean;
 function LZMAGetLevel(const Value: String; var Level: Integer): Boolean;

+ 39 - 152
Projects/Main.pas

@@ -167,7 +167,7 @@ var
   { Other }
   ShowLanguageDialog, MatchedLangParameter: Boolean;
   InstallMode: (imNormal, imSilent, imVerySilent);
-  HasIcons, IsNT, IsWin64, Is64BitInstallMode, IsAdmin, IsPowerUserOrAdmin, IsAdminInstallMode,
+  HasIcons, IsWin64, Is64BitInstallMode, IsAdmin, IsPowerUserOrAdmin, IsAdminInstallMode,
     NeedPassword, NeedSerial, NeedsRestart, RestartSystem,
     IsUninstaller, AllowUninstallerShutdown, AcceptedQueryEndSessionInProgress: Boolean;
   InstallDefaultDisableFsRedir, ScriptFuncDisableFsRedir: Boolean;
@@ -185,9 +185,7 @@ var
   SetupExitCode: Integer;
   CreatedIcon: Boolean;
   RestartInitiatedByThisProcess, DownloadTemporaryFileProcessMessages: Boolean;
-{$IFDEF IS_D12}
   TaskbarButtonHidden: Boolean;
-{$ENDIF}
   InstallModeRootKey: HKEY;
 
   CodeRunner: TScriptRunner;
@@ -271,7 +269,7 @@ uses
   Wizard, DebugClient, VerInfo, Extract, FileClass, Logging, MD5, SHA1,
   {$IFNDEF Delphi3orHigher} OLE2, {$ELSE} ActiveX, {$ENDIF}
   SimpleExpression, Helper, SpawnClient, SpawnServer, DotNet, BitmapImage,
-  TaskDialog;
+  TaskDialog, RegStr;
 
 {$R *.DFM}
 
@@ -347,7 +345,7 @@ end;
 
 function GetUninstallRegSubkeyName(const UninstallRegKeyBaseName: String): String;
 begin
-  Result := Format('%s\%s_is1', [NEWREGSTR_PATH_UNINSTALL, UninstallRegKeyBaseName]);
+  Result := Format('%s\%s_is1', [REGSTR_PATH_UNINSTALL, UninstallRegKeyBaseName]);
 end;
 
 { Based on FindPreviousData in Wizard.pas }
@@ -1299,7 +1297,7 @@ procedure InitMainNonSHFolderConsts;
   var
     H: HKEY;
   begin
-    if RegOpenKeyExView(RegView, HKEY_LOCAL_MACHINE, NEWREGSTR_PATH_SETUP, 0,
+    if RegOpenKeyExView(RegView, HKEY_LOCAL_MACHINE, REGSTR_PATH_SETUP, 0,
        KEY_QUERY_VALUE, H) = ERROR_SUCCESS then begin
       if not RegQueryStringValue(H, Name, Result) then
         Result := '';
@@ -1310,9 +1308,6 @@ procedure InitMainNonSHFolderConsts;
   end;
 
   procedure ReadSysUserInfo;
-  const
-    Paths: array[Boolean] of PChar = (NEWREGSTR_PATH_SETUP,
-      'SOFTWARE\Microsoft\Windows NT\CurrentVersion');
   var
     RegView: TRegView;
     K: HKEY;
@@ -1325,8 +1320,8 @@ procedure InitMainNonSHFolderConsts;
       RegView := rv64Bit
     else
       RegView := rvDefault;
-    if RegOpenKeyExView(RegView, HKEY_LOCAL_MACHINE, Paths[IsNT], 0, KEY_QUERY_VALUE,
-       K) = ERROR_SUCCESS then begin
+    if RegOpenKeyExView(RegView, HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows NT\CurrentVersion',
+       0, KEY_QUERY_VALUE, K) = ERROR_SUCCESS then begin
       RegQueryStringValue(K, 'RegisteredOwner', SysUserInfoName);
       RegQueryStringValue(K, 'RegisteredOrganization', SysUserInfoOrg);
       RegCloseKey(K);
@@ -1341,10 +1336,7 @@ begin
   WinSysNativeDir := GetSysNativeDir(IsWin64);
 
   { Get system drive }
-  if Win32Platform = VER_PLATFORM_WIN32_NT then
-    SystemDrive := GetEnv('SystemDrive')  {don't localize}
-  else
-    SystemDrive := '';
+  SystemDrive := GetEnv('SystemDrive');  {don't localize}
   if SystemDrive = '' then begin
     SystemDrive := PathExtractDrive(WinDir);
     if SystemDrive = '' then
@@ -1371,10 +1363,7 @@ begin
   end;
 
   { Get path of command interpreter }
-  if IsNT then
-    CmdFilename := AddBackslash(WinSystemDir) + 'cmd.exe'
-  else
-    CmdFilename := AddBackslash(WinDir) + 'COMMAND.COM';
+  CmdFilename := AddBackslash(WinSystemDir) + 'cmd.exe';
 
   { Get user info from system }
   ReadSysUserInfo;
@@ -1624,21 +1613,15 @@ var
   Ver, Ver2, MinVer, OnlyBelowVer: Cardinal;
 begin
   Ver := WindowsVersion;
-  if IsNT then begin
-    MinVer := MinVersion.NTVersion;
-    OnlyBelowVer := OnlyBelowVersion.NTVersion;
-  end
-  else begin
-    MinVer := 0;
-    OnlyBelowVer := 0;
-  end;
+  MinVer := MinVersion.NTVersion;
+  OnlyBelowVer := OnlyBelowVersion.NTVersion;
   Result := irInstall;
   if MinVer = 0 then
     Result := irNotOnThisPlatform
   else begin
     if Ver < MinVer then
       Result := irVersionTooLow
-    else if (IsNT and (LongRec(Ver).Hi = LongRec(MinVer).Hi) and
+    else if ((LongRec(Ver).Hi = LongRec(MinVer).Hi) and
         (NTServicePackLevel < MinVersion.NTServicePack)) then
       Result := irServicePackTooLow
     else begin
@@ -1647,23 +1630,17 @@ begin
         { A build number of 0 on OnlyBelowVersion means 'match any build' }
         if LongRec(OnlyBelowVer).Lo = 0 then
           Ver2 := Ver2 and $FFFF0000;  { set build number to zero on Ver2 also }
-        if not IsNT then begin
-          if Ver2 >= OnlyBelowVer then
-            Result := irVerTooHigh;
-        end
-        else begin
-          { Note: When OnlyBelowVersion includes a service pack level, the
-            version number test changes from a "<" to "<=" operation. Thus,
-            on Windows 2000 SP4, 5.0 and 5.0.2195 will fail, but 5.0sp5 and
-            5.0.2195sp5 will pass. }
-          if (Ver2 > OnlyBelowVer) or
-             ((Ver2 = OnlyBelowVer) and
-              (OnlyBelowVersion.NTServicePack = 0)) or
-             ((LongRec(Ver).Hi = LongRec(OnlyBelowVer).Hi) and
-              (OnlyBelowVersion.NTServicePack <> 0) and
-              (NTServicePackLevel >= OnlyBelowVersion.NTServicePack)) then
-            Result := irVerTooHigh;
-        end;
+        { Note: When OnlyBelowVersion includes a service pack level, the
+          version number test changes from a "<" to "<=" operation. Thus,
+          on Windows 2000 SP4, 5.0 and 5.0.2195 will fail, but 5.0sp5 and
+          5.0.2195sp5 will pass. }
+        if (Ver2 > OnlyBelowVer) or
+           ((Ver2 = OnlyBelowVer) and
+            (OnlyBelowVersion.NTServicePack = 0)) or
+           ((LongRec(Ver).Hi = LongRec(OnlyBelowVer).Hi) and
+            (OnlyBelowVersion.NTServicePack <> 0) and
+            (NTServicePackLevel >= OnlyBelowVersion.NTServicePack)) then
+          Result := irVerTooHigh;
       end;
     end;
   end;
@@ -1879,12 +1856,8 @@ var
   J: Integer;
 begin
   Filename := AFilename;
-  if IsNT then begin
-    if not DisableFsRedir then
-      Filename := ReplaceSystemDirWithSysWow64(Filename);
-  end
-  else
-    Filename := GetShortName(Filename);
+  if not DisableFsRedir then
+    Filename := ReplaceSystemDirWithSysWow64(Filename);
   Filename := PathLowercase(Filename);
   for J := 0 to CheckForFileSL.Count-1 do begin
     if CheckForFileSL[J] = Filename then begin
@@ -2154,14 +2127,6 @@ end;
 
 procedure SetActiveLanguage(const I: Integer);
 { Activates the specified language }
-const
-{$IFDEF UNICODE}
-  { UNICODE requires 2000+, so we can just use the English name }
-  SMSPGothic = 'MS PGothic';
-{$ELSE}
-  { "MS PGothic" in Japanese (CP 932) }
-  SMSPGothic = #$82'l'#$82'r '#$82'o'#$83'S'#$83'V'#$83'b'#$83'N';
-{$ENDIF}
 var
   LangEntry: PSetupLanguageEntry;
   J: Integer;
@@ -2181,30 +2146,6 @@ begin
   Finalize(LangOptions);  { prevent leak on D2 }
   LangOptions := LangEntry^;
 
-  { Hack for Japanese: Override the default fonts on older versions of Windows
-    that don't (fully) support font linking }
-  if (LangOptions.LanguageID = $0411) and
-{$IFNDEF UNICODE}
-     (GetACP = 932) and
-{$ENDIF}
-     (WindowsVersion < Cardinal($05010000)) and
-     FontExists(SMSPGothic) then begin
-    { Windows <= 2000: Verdana can't display Japanese }
-    LangOptions.WelcomeFontName := SMSPGothic;
-    LangOptions.WelcomeFontSize := 12;
-{$IFNDEF UNICODE}
-    if WindowsVersion < Cardinal($05000000) then begin
-      { Windows 9x/Me/NT 4.0: MS Sans Serif can't display Japanese }
-      LangOptions.DialogFontName := SMSPGothic;
-      LangOptions.DialogFontSize := 9;
-      LangOptions.TitleFontName := SMSPGothic;
-      LangOptions.TitleFontSize := 29;
-      LangOptions.CopyrightFontName := SMSPGothic;
-      LangOptions.CopyrightFontSize := 9;
-    end;
-{$ENDIF}
-  end;
-
   if LangEntry.LicenseText <> '' then
     ActiveLicenseText := LangEntry.LicenseText
   else
@@ -2283,9 +2224,7 @@ begin
     application window. We can't simply hide the window because on D3+ the VCL
     would just show it again in TApplication.UpdateVisible when the first form
     is shown. }
-{$IFDEF IS_D12}
   TaskbarButtonHidden := not AVisible;  { see WM_STYLECHANGING hook in Setup.dpr }
-{$ENDIF}
   if (GetWindowLong(Application.Handle, GWL_EXSTYLE) and WS_EX_TOOLWINDOW = 0) <> AVisible then begin
     SetWindowPos(Application.Handle, 0, 0, 0, 0, 0, SWP_NOSIZE or
       SWP_NOMOVE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_HIDEWINDOW);
@@ -2323,18 +2262,16 @@ begin
       SP := SP + '.' + IntToStr(Lo(NTServicePackLevel));
   end;
   LogFmt('Windows version: %u.%u.%u%s  (NT platform: %s)', [WindowsVersion shr 24,
-    (WindowsVersion shr 16) and $FF, WindowsVersion and $FFFF, SP, SYesNo[IsNT]]);
+    (WindowsVersion shr 16) and $FF, WindowsVersion and $FFFF, SP, SYesNo[True]]);
   LogFmt('64-bit Windows: %s', [SYesNo[IsWin64]]);
   LogFmt('Processor architecture: %s', [SetupProcessorArchitectureNames[ProcessorArchitecture]]);
 
-  if IsNT then begin
-    if IsAdmin then
-      Log('User privileges: Administrative')
-    else if IsPowerUserOrAdmin then
-      Log('User privileges: Power User')
-    else
-      Log('User privileges: None');
-  end;
+  if IsAdmin then
+    Log('User privileges: Administrative')
+  else if IsPowerUserOrAdmin then
+    Log('User privileges: Power User')
+  else
+    Log('User privileges: None');
 end;
 
 function GetMessageBoxResultText(const AResult: Integer): String;
@@ -3648,8 +3585,8 @@ begin
       BorderStyle := bsSingle;
 
     { Make the main window full-screen. If the window is resizable, limit it
-      to just the work area because on recent versions of Windows (e.g. 2000)
-      full-screen resizable windows don't cover over the taskbar. }
+      to just the work area because full-screen resizable windows don't cover
+      over the taskbar. }
     BoundsRect := GetRectOfPrimaryMonitor(BorderStyle = bsSizeable);
     { Before maximizing the window, ensure Handle is created now so the correct
       'restored' position is saved properly }
@@ -4468,45 +4405,6 @@ end;
 
 procedure InitWindowsVersion;
 
-  procedure ReadServicePackFromRegistry;
-  var
-    K: HKEY;
-    Size, Typ, SP: DWORD;
-  begin
-    if RegOpenKeyExView(rvDefault, HKEY_LOCAL_MACHINE, 'System\CurrentControlSet\Control\Windows',
-       0, KEY_QUERY_VALUE, K) = ERROR_SUCCESS then begin
-      Size := SizeOf(SP);
-      if (RegQueryValueEx(K, 'CSDVersion', nil, @Typ, @SP, @Size) = ERROR_SUCCESS) and
-         (Typ = REG_DWORD) and (Size = SizeOf(SP)) then
-        NTServicePackLevel := Word(SP);
-      RegCloseKey(K);
-    end;
-  end;
-
-  procedure ReadProductTypeFromRegistry;
-  const
-    VER_NT_WORKSTATION = 1;
-    VER_NT_DOMAIN_CONTROLLER = 2;
-    VER_NT_SERVER = 3;
-  var
-    K: HKEY;
-    S: String;
-  begin
-    if RegOpenKeyExView(rvDefault, HKEY_LOCAL_MACHINE, 'System\CurrentControlSet\Control\ProductOptions',
-       0, KEY_QUERY_VALUE, K) = ERROR_SUCCESS then begin
-      { See MS KB article 152078 for details on this key } 
-      if RegQueryStringValue(K, 'ProductType', S) then begin
-        if CompareText(S, 'WinNT') = 0 then
-          WindowsProductType := VER_NT_WORKSTATION
-        else if CompareText(S, 'LanmanNT') = 0 then
-          WindowsProductType := VER_NT_DOMAIN_CONTROLLER
-        else if CompareText(S, 'ServerNT') = 0 then
-          WindowsProductType := VER_NT_SERVER;
-      end;
-      RegCloseKey(K);
-    end;
-  end;
-
 type
   TOSVersionInfoEx = packed record
     dwOSVersionInfoSize: DWORD;
@@ -4531,22 +4429,12 @@ begin
       (Byte(OSVersionInfo.dwMinorVersion) shl 16) or
       Word(OSVersionInfo.dwBuildNumber);
     { ^ Note: We MUST clip dwBuildNumber to 16 bits for Win9x compatibility }
-    if IsNT then begin
-      if OSVersionInfo.dwMajorVersion >= 5 then begin
-        { OSVERSIONINFOEX is only available starting in Windows 2000 }
-        OSVersionInfoEx.dwOSVersionInfoSize := SizeOf(OSVersionInfoEx);
-        if GetVersionEx(POSVersionInfo(@OSVersionInfoEx)^) then begin
-          NTServicePackLevel := (Byte(OSVersionInfoEx.wServicePackMajor) shl 8) or
-            Byte(OSVersionInfoEx.wServicePackMinor);
-          WindowsProductType := OSVersionInfoEx.wProductType;
-          WindowsSuiteMask := OSVersionInfoEx.wSuiteMask;
-        end;
-      end
-      else if OSVersionInfo.dwMajorVersion = 4 then begin
-        { Read from the registry on NT 4 }
-        ReadServicePackFromRegistry;
-        ReadProductTypeFromRegistry;
-      end;
+    OSVersionInfoEx.dwOSVersionInfoSize := SizeOf(OSVersionInfoEx);
+    if GetVersionEx(POSVersionInfo(@OSVersionInfoEx)^) then begin
+      NTServicePackLevel := (Byte(OSVersionInfoEx.wServicePackMajor) shl 8) or
+        Byte(OSVersionInfoEx.wServicePackMinor);
+      WindowsProductType := OSVersionInfoEx.wProductType;
+      WindowsSuiteMask := OSVersionInfoEx.wSuiteMask;
     end;
   end;
 end;
@@ -4596,7 +4484,6 @@ begin
 end;
 
 initialization
-  IsNT := UsingWinNT;
   InitIsWin64AndProcessorArchitecture;
   InitWindowsVersion;
 {$IFNDEF UNICODE}

+ 4 - 6
Projects/RedirFunc.pas

@@ -2,7 +2,7 @@ unit RedirFunc;
 
 {
   Inno Setup
-  Copyright (C) 1997-2007 Jordan Russell
+  Copyright (C) 1997-2024 Jordan Russell
   Portions by Martijn Laan
   For conditions of distribution and use, see LICENSE.TXT.
 
@@ -123,10 +123,8 @@ function DisableFsRedirectionIf(const Disable: Boolean;
   If Disable is True, the function attempts to disable WOW64 file system
   redirection, so that c:\windows\system32 goes to the 64-bit System directory
   instead of the 32-bit one.
-  Returns True if successful, False if not (which normally indicates that
-  either the user is running 32-bit Windows, or a 64-bit version prior to
-  Windows Server 2003 SP1). For extended error information when False is
-  returned, call GetLastError. }
+  Returns True if successful, False if not. For extended error information when
+  False is returned, call GetLastError. }
 begin
   PreviousState.DidDisable := False;
   if not Disable then
@@ -142,7 +140,7 @@ begin
         PreviousState.DidDisable := True;
     end
     else begin
-      { The functions do not exist prior to Windows Server 2003 SP1 }
+      { Should never happen }
       SetLastError(ERROR_INVALID_FUNCTION);
       Result := False;
     end;

+ 1 - 1
Projects/SafeDLLPath.pas

@@ -12,7 +12,7 @@ unit SafeDLLPath;
   
   If SetDefaultDllDirectories is not available:
   -It calls SetDllDirectory('') to prevent LoadLibrary from searching the current
-   directory for DLLs. (Has no effect on Windows versions prior to XP SP1.)
+   directory for DLLs.
   -It then preloads a list of system DLLs which are known to be loaded unsafely
    by older or unpatched versions of Windows.
 

+ 3 - 3
Projects/ScriptFunc_R.pas

@@ -2,7 +2,7 @@ unit ScriptFunc_R;
 
 {
   Inno Setup
-  Copyright (C) 1997-2020 Jordan Russell
+  Copyright (C) 1997-2024 Jordan Russell
   Portions by Martijn Laan
   For conditions of distribution and use, see LICENSE.TXT.
 
@@ -575,7 +575,7 @@ begin
     Stack.SetInt(PStart, StringChangeEx(S, Stack.GetString(PStart-2), Stack.GetString(PStart-3), Stack.GetBool(PStart-4)));
     Stack.SetString(PStart-1, S);
   end else if Proc.Name = 'USINGWINNT' then begin
-    Stack.SetBool(PStart, UsingWinNT());
+    Stack.SetBool(PStart, True);
   end else if Proc.Name = 'FILECOPY' then begin
     ExistingFilename := Stack.GetString(PStart-1);
     if PathCompare(ExistingFilename, SetupLdrOriginalFilename) <> 0 then
@@ -1164,7 +1164,7 @@ begin
   Version.Build := WindowsVersion and $FFFF;
   Version.ServicePackMajor := Hi(NTServicePackLevel);
   Version.ServicePackMinor := Lo(NTServicePackLevel);
-  Version.NTPlatform := IsNT;
+  Version.NTPlatform := True;
   Version.ProductType := WindowsProductType;
   Version.SuiteMask := WindowsSuiteMask;
 end;

+ 42 - 67
Projects/SecurityFunc.pas

@@ -2,13 +2,11 @@ unit SecurityFunc;
 
 {
   Inno Setup
-  Copyright (C) 1997-2008 Jordan Russell
+  Copyright (C) 1997-2024 Jordan Russell
   Portions by Martijn Laan
   For conditions of distribution and use, see LICENSE.TXT.
 
   Functions for altering ACLs on files & registry keys
-
-  $jrsoftware: issrc/Projects/SecurityFunc.pas,v 1.6 2008/10/17 22:18:14 jr Exp $
 }
 
 interface
@@ -59,7 +57,7 @@ function InternalGrantPermission(const ObjectType: DWORD; const ObjectName: Stri
   const Entries: TGrantPermissionEntry; const EntryCount: Integer;
   const Inheritance: DWORD): DWORD;
 { Grants the specified access to the specified object. Returns ERROR_SUCCESS if
-  successful. Always fails on Windows 9x/Me and NT 4.0. }
+  successful. }
 type
   PPSID = ^PSID;
   PPACL = ^PACL;
@@ -95,9 +93,6 @@ var
   SetEntriesInAclW: function(cCountOfExplicitEntries: ULONG;
     const pListOfExplicitEntries: TExplicitAccessW; OldAcl: PACL;
     var NewAcl: PACL): DWORD; stdcall;
-  {$IFNDEF UNICODE}
-  WideObjectName: PWideChar;
-  {$ENDIF}
   SD: PSECURITY_DESCRIPTOR;
   Dacl, NewDacl: PACL;
   ExplicitAccess: PArrayOfExplicitAccessW;
@@ -105,13 +100,6 @@ var
   I: Integer;
   Sid: PSID;
 begin
-  { Windows 9x/Me don't support ACLs, and GetNamedSecurityInfo and
-    SetEntriesInACL are buggy on NT 4 }
-  if (Win32Platform <> VER_PLATFORM_WIN32_NT) or (Lo(GetVersion) < 5) then begin
-    Result := ERROR_INVALID_FUNCTION;
-    Exit;
-  end;
-
   AdvApiHandle := GetModuleHandle(advapi32);
   GetNamedSecurityInfoW := GetProcAddress(AdvApiHandle, PAnsiChar('GetNamedSecurityInfoW'));
   SetNamedSecurityInfoW := GetProcAddress(AdvApiHandle, PAnsiChar('SetNamedSecurityInfoW'));
@@ -122,63 +110,52 @@ begin
     Exit;
   end;
 
-  {$IFNDEF UNICODE}
-  WideObjectName := AllocWideCharStr(ObjectName);
+  ExplicitAccess := nil;
+  Result := GetNamedSecurityInfoW(PChar(ObjectName), ObjectType,
+    DACL_SECURITY_INFORMATION, nil, nil, @Dacl, nil, SD);
+  if Result <> ERROR_SUCCESS then
+    Exit;
   try
-  {$ENDIF}
-    ExplicitAccess := nil;
-    Result := GetNamedSecurityInfoW(
-      {$IFDEF UNICODE} PChar(ObjectName) {$ELSE} WideObjectName {$ENDIF},
-      ObjectType, DACL_SECURITY_INFORMATION, nil, nil, @Dacl, nil, SD);
+    { Note: Dacl will be nil if GetNamedSecurityInfo is called on a FAT partition.
+      Be careful not to dereference a nil pointer. }
+    ExplicitAccess := AllocMem(EntryCount * SizeOf(ExplicitAccess[0]));
+    E := @Entries;
+    for I := 0 to EntryCount-1 do begin
+      if not AllocateAndInitializeSid(E.Sid.Authority, E.Sid.SubAuthCount,
+         E.Sid.SubAuth[0], E.Sid.SubAuth[1], 0, 0, 0, 0, 0, 0, Sid) then begin
+        Result := GetLastError;
+        if Result = ERROR_SUCCESS then  { just in case... }
+          Result := ERROR_INVALID_PARAMETER;
+        Exit;
+      end;
+      ExplicitAccess[I].grfAccessPermissions := E.AccessMask;
+      ExplicitAccess[I].grfAccessMode := GRANT_ACCESS;
+      ExplicitAccess[I].grfInheritance := Inheritance;
+      ExplicitAccess[I].Trustee.TrusteeForm := TRUSTEE_IS_SID;
+      ExplicitAccess[I].Trustee.TrusteeType := TRUSTEE_IS_UNKNOWN;
+      PSID(ExplicitAccess[I].Trustee.ptstrName) := Sid;
+      Inc(E);
+    end;
+    Result := SetEntriesInAclW(EntryCount, ExplicitAccess[0], Dacl, NewDacl);
     if Result <> ERROR_SUCCESS then
       Exit;
     try
-      { Note: Dacl will be nil if GetNamedSecurityInfo is called on a FAT partition.
-        Be careful not to dereference a nil pointer. }
-      ExplicitAccess := AllocMem(EntryCount * SizeOf(ExplicitAccess[0]));
-      E := @Entries;
-      for I := 0 to EntryCount-1 do begin
-        if not AllocateAndInitializeSid(E.Sid.Authority, E.Sid.SubAuthCount,
-           E.Sid.SubAuth[0], E.Sid.SubAuth[1], 0, 0, 0, 0, 0, 0, Sid) then begin
-          Result := GetLastError;
-          if Result = ERROR_SUCCESS then  { just in case... }
-            Result := ERROR_INVALID_PARAMETER;
-          Exit;
-        end;
-        ExplicitAccess[I].grfAccessPermissions := E.AccessMask;
-        ExplicitAccess[I].grfAccessMode := GRANT_ACCESS;
-        ExplicitAccess[I].grfInheritance := Inheritance;
-        ExplicitAccess[I].Trustee.TrusteeForm := TRUSTEE_IS_SID;
-        ExplicitAccess[I].Trustee.TrusteeType := TRUSTEE_IS_UNKNOWN;
-        PSID(ExplicitAccess[I].Trustee.ptstrName) := Sid;
-        Inc(E);
-      end;
-      Result := SetEntriesInAclW(EntryCount, ExplicitAccess[0], Dacl, NewDacl);
-      if Result <> ERROR_SUCCESS then
-        Exit;
-      try
-        Result := SetNamedSecurityInfoW(
-          {$IFDEF UNICODE} PChar(ObjectName) {$ELSE} WideObjectName {$ENDIF},
-          ObjectType, DACL_SECURITY_INFORMATION, nil, nil, NewDacl, nil);
-      finally
-        LocalFree(HLOCAL(NewDacl));
-      end;
+      Result := SetNamedSecurityInfoW(PChar(ObjectName), ObjectType,
+        DACL_SECURITY_INFORMATION, nil, nil, NewDacl, nil);
     finally
-      if Assigned(ExplicitAccess) then begin
-        for I := EntryCount-1 downto 0 do begin
-          Sid := PSID(ExplicitAccess[I].Trustee.ptstrName);
-          if Assigned(Sid) then
-            FreeSid(Sid);
-        end;
-        FreeMem(ExplicitAccess);
-      end;
-      LocalFree(HLOCAL(SD));
+      LocalFree(HLOCAL(NewDacl));
     end;
-  {$IFNDEF UNICODE}
   finally
-    FreeMem(WideObjectName);
+    if Assigned(ExplicitAccess) then begin
+      for I := EntryCount-1 downto 0 do begin
+        Sid := PSID(ExplicitAccess[I].Trustee.ptstrName);
+        if Assigned(Sid) then
+          FreeSid(Sid);
+      end;
+      FreeMem(ExplicitAccess);
+    end;
+    LocalFree(HLOCAL(SD));
   end;
-  {$ENDIF}
 end;
 
 function GrantPermission(const Use64BitHelper: Boolean; const ObjectType: DWORD;
@@ -210,8 +187,7 @@ const
 function GrantPermissionOnFile(const DisableFsRedir: Boolean; Filename: String;
   const Entries: TGrantPermissionEntry; const EntryCount: Integer): Boolean;
 { Grants the specified access to the specified file/directory. Returns True if
-  successful. On failure, the thread's last error code is set. Always fails on
-  Windows 9x/Me and NT 4.0. }
+  successful. On failure, the thread's last error code is set. }
 const
   SE_FILE_OBJECT = 1;
 var
@@ -239,8 +215,7 @@ function GrantPermissionOnKey(const RegView: TRegView; const RootKey: HKEY;
   const Subkey: String; const Entries: TGrantPermissionEntry;
   const EntryCount: Integer): Boolean;
 { Grants the specified access to the specified registry key. Returns True if
-  successful. On failure, the thread's last error code is set. Always fails on
-  Windows 9x/Me and NT 4.0. }
+  successful. On failure, the thread's last error code is set. }
 const
   SE_REGISTRY_KEY = 4;
 var

+ 5 - 11
Projects/SelFolderForm.pas

@@ -2,13 +2,11 @@ unit SelFolderForm;
 
 {
   Inno Setup
-  Copyright (C) 1997-2004 Jordan Russell
+  Copyright (C) 1997-2024 Jordan Russell
   Portions by Martijn Laan
   For conditions of distribution and use, see LICENSE.TXT.
 
   "Select Folder" form
-
-  $jrsoftware: issrc/Projects/SelFolderForm.pas,v 1.15 2010/10/22 10:33:26 mlaan Exp $
 }
 
 interface
@@ -60,14 +58,10 @@ begin
     Form.NewFolderButton.Visible := not AppendDir and (NewFolderName <> '');
     if StartMenu then begin
       with Form.FFolderTreeView as TStartMenuFolderTreeView do
-        if IsNT then
-          SetPaths(GetShellFolder(False, sfPrograms),
-            GetShellFolder(True, sfPrograms),
-            GetShellFolder(False, sfStartup),
-            GetShellFolder(True, sfStartup))
-        else
-          SetPaths(GetShellFolder(False, sfPrograms),
-            '', GetShellFolder(False, sfStartup), '');
+        SetPaths(GetShellFolder(False, sfPrograms),
+          GetShellFolder(True, sfPrograms),
+          GetShellFolder(False, sfStartup),
+          GetShellFolder(True, sfStartup));
       TidyUpGroupName(Path);
     end
     else

+ 0 - 2
Projects/Setup.dpr

@@ -186,8 +186,6 @@ procedure DisableWindowGhosting;
 var
   Proc: procedure; stdcall;
 begin
-  { Note: The documentation claims this function is only available in XP SP1,
-    but it's actually available on stock XP too. }
   Proc := GetProcAddress(GetModuleHandle(user32), 'DisableProcessWindowsGhosting');
   if Assigned(Proc) then
     Proc;

+ 3 - 5
Projects/UIStateForm.pas

@@ -2,15 +2,13 @@ unit UIStateForm;
 
 {
   Inno Setup
-  Copyright (C) 1997-2004 Jordan Russell
+  Copyright (C) 1997-2024 Jordan Russell
   Portions by Martijn Laan
   For conditions of distribution and use, see LICENSE.TXT.
 
   TUIStateForm, a TForm descendant which correctly handles the hiding of
-  accelerator key characters and focus rectangles on Windows 2000 and later
-  when the "Hide keyboard navigation indicators" option is enabled.
-
-  $jrsoftware: issrc/Projects/UIStateForm.pas,v 1.2 2004/06/26 04:36:08 jr Exp $
+  accelerator key characters and focus rectangles when the
+  "Hide keyboard navigation indicators" option is enabled.
 }
 
 interface

+ 1 - 4
Projects/Undo.pas

@@ -301,10 +301,7 @@ begin
         DirsNotRemoved.AddIfDoesntExist(DirsNotRemovedPrefix[DisableFsRedir] + DirName);
       end
       else if Assigned(RestartDeleteDirList) and
-         ListContainsPathOrSubdir(RestartDeleteDirList, DirName) and
-         (Win32Platform = VER_PLATFORM_WIN32_NT) then begin
-        { Note: This code is NT-only; I don't think it's possible to
-          restart-delete directories on Windows 9x. }
+         ListContainsPathOrSubdir(RestartDeleteDirList, DirName) then begin
         LogFmt('Failed to delete directory (%d). Will delete on restart (if empty).',
           [LastError]);
         LoggedRestartDeleteDir(DisableFsRedir, DirName);

+ 3 - 4
Projects/Verinfo.pas → Projects/VerInfo.pas

@@ -2,7 +2,7 @@ unit VerInfo;
 
 {
   Inno Setup
-  Copyright (C) 1997-2020 Jordan Russell
+  Copyright (C) 1997-2024 Jordan Russell
   Portions by Martijn Laan
   For conditions of distribution and use, see LICENSE.TXT.
 
@@ -193,9 +193,8 @@ begin
     finally
       FreeMem(VersionBuf);
     end;
-  end
-  else if Win32Platform <> VER_PLATFORM_WIN32_WINDOWS then begin
-    { NT's version APIs don't support VXDs, so use our own code to handle them }
+  end else begin
+    { Windows' version APIs don't support VXDs, so use our own code to handle them }
     Result := GetVXDVersionInfo(Filename, VersionInfo);
   end;
 end;