소스 검색

Add IsX64Compatible internal variable which will be False on X64 but True on ARM64 on Windows 11 (based on GetMachineTypeAttributes). Logged if not on X64 and otherwise currently only used for new IsX64Compatible support function.

Martijn Laan 1 년 전
부모
커밋
94be3b3720
3개의 변경된 파일26개의 추가작업 그리고 6개의 파일을 삭제
  1. 22 5
      Projects/Src/Main.pas
  2. 2 1
      Projects/Src/ScriptFunc.pas
  3. 2 0
      Projects/Src/ScriptFunc_R.pas

+ 22 - 5
Projects/Src/Main.pas

@@ -172,6 +172,7 @@ var
   InstallDefaultRegView: TRegView = rvDefault;
   InstallDefaultRegView: TRegView = rvDefault;
   HasCustomType, HasComponents, HasTasks: Boolean;
   HasCustomType, HasComponents, HasTasks: Boolean;
   ProcessorArchitecture: TSetupProcessorArchitecture = paUnknown;
   ProcessorArchitecture: TSetupProcessorArchitecture = paUnknown;
+  IsX64Compatible: Boolean;
   WindowsVersion: Cardinal;
   WindowsVersion: Cardinal;
   NTServicePackLevel: Word;
   NTServicePackLevel: Word;
   WindowsProductType: Byte;
   WindowsProductType: Byte;
@@ -2269,6 +2270,8 @@ begin
     (WindowsVersion shr 16) and $FF, WindowsVersion and $FFFF, SP, SYesNo[True]]);
     (WindowsVersion shr 16) and $FF, WindowsVersion and $FFFF, SP, SYesNo[True]]);
   LogFmt('64-bit Windows: %s', [SYesNo[IsWin64]]);
   LogFmt('64-bit Windows: %s', [SYesNo[IsWin64]]);
   LogFmt('Processor architecture: %s', [SetupProcessorArchitectureNames[ProcessorArchitecture]]);
   LogFmt('Processor architecture: %s', [SetupProcessorArchitectureNames[ProcessorArchitecture]]);
+  if ProcessorArchitecture <> paX64 then
+    LogFmt('Processor architecture is X64 compatible: %s', [SYesNo[IsX64Compatible]]);
 
 
   if IsAdmin then
   if IsAdmin then
     Log('User privileges: Administrative')
     Log('User privileges: Administrative')
@@ -4328,7 +4331,7 @@ begin
 end;
 end;
 
 
 
 
-procedure InitIsWin64AndProcessorArchitecture;
+procedure InitIsWin64AndProcessorArchitectureAndIsX64Compatible;
 const
 const
   PROCESSOR_ARCHITECTURE_INTEL = 0;
   PROCESSOR_ARCHITECTURE_INTEL = 0;
   PROCESSOR_ARCHITECTURE_IA64 = 6;
   PROCESSOR_ARCHITECTURE_IA64 = 6;
@@ -4338,15 +4341,22 @@ const
   IMAGE_FILE_MACHINE_IA64 = $0200;
   IMAGE_FILE_MACHINE_IA64 = $0200;
   IMAGE_FILE_MACHINE_AMD64 = $8664;
   IMAGE_FILE_MACHINE_AMD64 = $8664;
   IMAGE_FILE_MACHINE_ARM64 = $AA64;
   IMAGE_FILE_MACHINE_ARM64 = $AA64;
+  UserEnabled = $1;
+  Wow64Container = $4;
 var
 var
   KernelModule: HMODULE;
   KernelModule: HMODULE;
   GetNativeSystemInfoFunc: procedure(var lpSystemInfo: TSystemInfo); stdcall;
   GetNativeSystemInfoFunc: procedure(var lpSystemInfo: TSystemInfo); stdcall;
   IsWow64ProcessFunc: function(hProcess: THandle; var Wow64Process: BOOL): BOOL; stdcall;
   IsWow64ProcessFunc: function(hProcess: THandle; var Wow64Process: BOOL): BOOL; stdcall;
   IsWow64Process2Func: function(hProcess: THandle; var pProcessMachine, pNativeMachine: USHORT): BOOL; stdcall;
   IsWow64Process2Func: function(hProcess: THandle; var pProcessMachine, pNativeMachine: USHORT): BOOL; stdcall;
+  GetMachineTypeAttributesFunc: function(Machine: Word; var MachineTypeAttributes: Integer): HRESULT; stdcall;
   ProcessMachine, NativeMachine: USHORT;
   ProcessMachine, NativeMachine: USHORT;
   Wow64Process: BOOL;
   Wow64Process: BOOL;
   SysInfo: TSystemInfo;
   SysInfo: TSystemInfo;
 begin
 begin
+  IsWin64 := False;
+  IsX64Compatible := False;
+  KernelModule := GetModuleHandle(kernel32);
+
   { The system is considered a "Win64" system if all of the following
   { The system is considered a "Win64" system if all of the following
     conditions are true:
     conditions are true:
     1. One of the following two is true:
     1. One of the following two is true:
@@ -4360,9 +4370,6 @@ begin
     The system does not have to be one of the known 64-bit architectures
     The system does not have to be one of the known 64-bit architectures
     (AMD64, IA64, ARM64) to be considered a "Win64" system. }
     (AMD64, IA64, ARM64) to be considered a "Win64" system. }
 
 
-  IsWin64 := False;
-  KernelModule := GetModuleHandle(kernel32);
-
   IsWow64Process2Func := GetProcAddress(KernelModule, 'IsWow64Process2');
   IsWow64Process2Func := GetProcAddress(KernelModule, 'IsWow64Process2');
   if Assigned(IsWow64Process2Func) and
   if Assigned(IsWow64Process2Func) and
      IsWow64Process2Func(GetCurrentProcess, ProcessMachine, NativeMachine) and
      IsWow64Process2Func(GetCurrentProcess, ProcessMachine, NativeMachine) and
@@ -4403,6 +4410,16 @@ begin
           (GetProcAddress(KernelModule, 'GetSystemWow64DirectoryA') <> nil) and
           (GetProcAddress(KernelModule, 'GetSystemWow64DirectoryA') <> nil) and
           (GetProcAddress(GetModuleHandle(advapi32), 'RegDeleteKeyExA') <> nil)) then
           (GetProcAddress(GetModuleHandle(advapi32), 'RegDeleteKeyExA') <> nil)) then
     IsWin64 := False;
     IsWin64 := False;
+
+  if (ProcessorArchitecture <> paX64) and IsWindows11 then begin
+    GetMachineTypeAttributesFunc := GetProcAddress(KernelModule, 'GetMachineTypeAttributes');
+    if Assigned(GetMachineTypeAttributesFunc) then begin
+      var MachineTypeAttributes: Integer;
+      if SUCCEEDED(GetMachineTypeAttributesFunc(IMAGE_FILE_MACHINE_AMD64, MachineTypeAttributes)) then
+        IsX64Compatible := ((MachineTypeAttributes and UserEnabled) <> 0) and
+                           ((MachineTypeAttributes and Wow64Container) = 0);
+    end;
+  end;
 end;
 end;
 
 
 procedure InitWindowsVersion;
 procedure InitWindowsVersion;
@@ -4486,8 +4503,8 @@ begin
 end;
 end;
 
 
 initialization
 initialization
-  InitIsWin64AndProcessorArchitecture;
   InitWindowsVersion;
   InitWindowsVersion;
+  InitIsWin64AndProcessorArchitectureAndIsX64Compatible;
   InitComponents := TStringList.Create();
   InitComponents := TStringList.Create();
   InitTasks := TStringList.Create();
   InitTasks := TStringList.Create();
   NewParamsForCode := TStringList.Create();
   NewParamsForCode := TStringList.Create();

+ 2 - 1
Projects/Src/ScriptFunc.pas

@@ -201,7 +201,7 @@ const
   );
   );
 
 
   { Main }
   { Main }
-  MainTable: array [0..28] of AnsiString =
+  MainTable: array [0..29] of AnsiString =
   (
   (
     'function GetWizardForm: TWizardForm;',
     'function GetWizardForm: TWizardForm;',
     'function GetMainForm: TMainForm;',
     'function GetMainForm: TMainForm;',
@@ -227,6 +227,7 @@ const
     'function ProcessorArchitecture: TSetupProcessorArchitecture;',
     'function ProcessorArchitecture: TSetupProcessorArchitecture;',
     'function IsX86: Boolean;',
     'function IsX86: Boolean;',
     'function IsX64: Boolean;',
     'function IsX64: Boolean;',
+    'function IsX64Compatible: Boolean;',
     'function IsIA64: Boolean;',
     'function IsIA64: Boolean;',
     'function IsARM64: Boolean;',
     'function IsARM64: Boolean;',
     'function CustomMessage(const MsgName: String): String;',
     'function CustomMessage(const MsgName: String): String;',

+ 2 - 0
Projects/Src/ScriptFunc_R.pas

@@ -1098,6 +1098,8 @@ begin
     Stack.SetBool(PStart, ProcessorArchitecture = paX86);
     Stack.SetBool(PStart, ProcessorArchitecture = paX86);
   end else if Proc.Name = 'ISX64' then begin
   end else if Proc.Name = 'ISX64' then begin
     Stack.SetBool(PStart, ProcessorArchitecture = paX64);
     Stack.SetBool(PStart, ProcessorArchitecture = paX64);
+  end else if Proc.Name = 'ISX64COMPATIBLE' then begin
+    Stack.SetBool(PStart, IsX64Compatible);
   end else if Proc.Name = 'ISIA64' then begin
   end else if Proc.Name = 'ISIA64' then begin
     Stack.SetBool(PStart, ProcessorArchitecture = paIA64);
     Stack.SetBool(PStart, ProcessorArchitecture = paIA64);
   end else if Proc.Name = 'ISARM64' then begin
   end else if Proc.Name = 'ISARM64' then begin