Skip to content

Commit 7eb934d

Browse files
committed
Add support for ARM/ARM64 architecture
Implemented function Win32::GetChipArch(). Win32::GetChipName() uses a deprecated member of struct SYSTEM_INFO ("An obsolete member that is retained for compatibility") not available for ARM64. Details: https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info In test cpan/Win32/t/Names.t, added explicit values possible for Win32::GetChipName() and Win32::GetChipArch().
1 parent 62a9e13 commit 7eb934d

File tree

3 files changed

+49
-6
lines changed

3 files changed

+49
-6
lines changed

Win32.pm

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,8 @@ sub PRODUCT_EDUCATION_N () { 0x7A } # Windows 10 Education
306306

307307
sub PRODUCT_UNLICENSED () { 0xABCDABCD } # product has not been activated and is no longer in the grace period
308308

309+
sub PROCESSOR_ARCHITECTURE_ARM64 () { 12 } # ARM64
310+
sub PROCESSOR_ARCHITECTURE_ARM () { 5 } # ARM
309311
sub PROCESSOR_ARCHITECTURE_AMD64 () { 9 } # x64 (AMD or Intel)
310312
sub PROCESSOR_ARCHITECTURE_IA64 () { 6 } # Intel Itanium Processor Family (IPF)
311313
sub PROCESSOR_ARCHITECTURE_INTEL () { 0 } # x86
@@ -319,6 +321,14 @@ sub _GetProcessorArchitecture {
319321
2200 => PROCESSOR_ARCHITECTURE_IA64,
320322
8664 => PROCESSOR_ARCHITECTURE_AMD64,
321323
}->{Win32::GetChipName()};
324+
325+
if (!defined($arch)) {
326+
$arch = {
327+
5 => PROCESSOR_ARCHITECTURE_ARM,
328+
12 => PROCESSOR_ARCHITECTURE_ARM64,
329+
}->{Win32::GetChipArch()};
330+
}
331+
322332
return defined($arch) ? $arch : PROCESSOR_ARCHITECTURE_UNKNOWN;
323333
}
324334

@@ -890,10 +900,17 @@ $ENV{PROCESSOR_ARCHITECTURE}. This might not work on Win9X.
890900
891901
=item Win32::GetChipName()
892902
893-
Returns the processor type: 386, 486 or 586 for x86 processors, 8664
894-
for the x64 processor and 2200 for the Itanium. Since it returns the
895-
native processor type it will return a 64-bit processor type even when
896-
called from a 32-bit Perl running on 64-bit Windows.
903+
Returns the processor type: 386, 486 or 586 for x86 processors, 8664 for the x64
904+
processor and 2200 for the Itanium. For arm/arm64 processor, the value is marked
905+
as "Reserved" (not specified, but usually 0) in Microsoft documentation, so it's
906+
better to use GetChipArch(). Since it returns the native processor type it will
907+
return a 64-bit processor type even when called from a 32-bit Perl running on
908+
64-bit Windows.
909+
910+
=item Win32::GetChipArch()
911+
912+
Returns the processor architecture: 0 for x86 processors, 5 for arm, 6 for
913+
Itanium, 9 for x64 and 12 for arm64, and 0xFFFF for unknown architecture.
897914
898915
=item Win32::GetConsoleCP()
899916

Win32.xs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,26 @@ XS(w32_GetArchName)
671671
XSRETURN_PV(getenv("PROCESSOR_ARCHITECTURE"));
672672
}
673673

674+
XS(w32_GetChipArch)
675+
{
676+
dXSARGS;
677+
SYSTEM_INFO sysinfo;
678+
HMODULE module;
679+
PFNGetNativeSystemInfo pfnGetNativeSystemInfo;
680+
if (items)
681+
Perl_croak(aTHX_ "usage: Win32::GetChipArch()");
682+
683+
Zero(&sysinfo,1,SYSTEM_INFO);
684+
module = GetModuleHandle("kernel32.dll");
685+
GETPROC(GetNativeSystemInfo);
686+
if (pfnGetNativeSystemInfo)
687+
pfnGetNativeSystemInfo(&sysinfo);
688+
else
689+
GetSystemInfo(&sysinfo);
690+
691+
XSRETURN_IV(sysinfo.wProcessorArchitecture);
692+
}
693+
674694
XS(w32_GetChipName)
675695
{
676696
dXSARGS;
@@ -2021,6 +2041,7 @@ BOOT:
20212041
newXS("Win32::RegisterServer", w32_RegisterServer, file);
20222042
newXS("Win32::UnregisterServer", w32_UnregisterServer, file);
20232043
newXS("Win32::GetArchName", w32_GetArchName, file);
2044+
newXS("Win32::GetChipArch", w32_GetChipArch, file);
20242045
newXS("Win32::GetChipName", w32_GetChipName, file);
20252046
newXS("Win32::GuidGen", w32_GuidGen, file);
20262047
newXS("Win32::GetFolderPath", w32_GetFolderPath, file);

t/Names.t

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ BEGIN {
77
}
88
use Win32;
99

10-
my $tests = 14;
10+
my $tests = 16;
1111
$tests += 2 if Win32::IsWinNT();
1212

1313
plan tests => $tests;
@@ -28,10 +28,15 @@ my $archname = eval { Win32::GetArchName() };
2828
is( $@, '', "Win32::GetArchName()" );
2929
cmp_ok( length($archname), '>=', 3, " - checking returned architecture name" );
3030

31+
# test Win32::GetChipArch()
32+
my $chiparch = eval { Win32::GetChipArch() };
33+
is( $@, '', "Win32::GetChipArch()" );
34+
like( $chiparch, '/^(0|5|6|9|12)$/', " - checking returned chip arch" );
35+
3136
# test Win32::GetChipName()
3237
my $chipname = eval { Win32::GetChipName() };
3338
is( $@, '', "Win32::GetChipName()" );
34-
cmp_ok( length($chipname), '>=', 3, " - checking returned chip name" );
39+
like( $chipname, '/^(0|386|486|586|2200|8664)$/', " - checking returned chip name");
3540

3641
# test Win32::GetOSName()
3742
# - scalar context

0 commit comments

Comments
 (0)