1package Win32; 2 3# BEGIN { 4 use strict; 5 use vars qw|$VERSION $XS_VERSION @ISA @EXPORT @EXPORT_OK|; 6 7 require Exporter; 8 require DynaLoader; 9 10 @ISA = qw|Exporter DynaLoader|; 11 $VERSION = '0.59'; 12 $XS_VERSION = $VERSION; 13 $VERSION = eval $VERSION; 14 15 @EXPORT = qw( 16 NULL 17 WIN31_CLASS 18 OWNER_SECURITY_INFORMATION 19 GROUP_SECURITY_INFORMATION 20 DACL_SECURITY_INFORMATION 21 SACL_SECURITY_INFORMATION 22 MB_ICONHAND 23 MB_ICONQUESTION 24 MB_ICONEXCLAMATION 25 MB_ICONASTERISK 26 MB_ICONWARNING 27 MB_ICONERROR 28 MB_ICONINFORMATION 29 MB_ICONSTOP 30 ); 31 @EXPORT_OK = qw( 32 GetOSName 33 SW_HIDE 34 SW_SHOWNORMAL 35 SW_SHOWMINIMIZED 36 SW_SHOWMAXIMIZED 37 SW_SHOWNOACTIVATE 38 39 CSIDL_DESKTOP 40 CSIDL_PROGRAMS 41 CSIDL_PERSONAL 42 CSIDL_FAVORITES 43 CSIDL_STARTUP 44 CSIDL_RECENT 45 CSIDL_SENDTO 46 CSIDL_STARTMENU 47 CSIDL_MYMUSIC 48 CSIDL_MYVIDEO 49 CSIDL_DESKTOPDIRECTORY 50 CSIDL_NETHOOD 51 CSIDL_FONTS 52 CSIDL_TEMPLATES 53 CSIDL_COMMON_STARTMENU 54 CSIDL_COMMON_PROGRAMS 55 CSIDL_COMMON_STARTUP 56 CSIDL_COMMON_DESKTOPDIRECTORY 57 CSIDL_APPDATA 58 CSIDL_PRINTHOOD 59 CSIDL_LOCAL_APPDATA 60 CSIDL_COMMON_FAVORITES 61 CSIDL_INTERNET_CACHE 62 CSIDL_COOKIES 63 CSIDL_HISTORY 64 CSIDL_COMMON_APPDATA 65 CSIDL_WINDOWS 66 CSIDL_SYSTEM 67 CSIDL_PROGRAM_FILES 68 CSIDL_MYPICTURES 69 CSIDL_PROFILE 70 CSIDL_PROGRAM_FILES_COMMON 71 CSIDL_COMMON_TEMPLATES 72 CSIDL_COMMON_DOCUMENTS 73 CSIDL_COMMON_ADMINTOOLS 74 CSIDL_ADMINTOOLS 75 CSIDL_COMMON_MUSIC 76 CSIDL_COMMON_PICTURES 77 CSIDL_COMMON_VIDEO 78 CSIDL_RESOURCES 79 CSIDL_RESOURCES_LOCALIZED 80 CSIDL_CDBURN_AREA 81 ); 82# } 83 84# We won't bother with the constant stuff, too much of a hassle. Just hard 85# code it here. 86 87sub NULL { 0 } 88sub WIN31_CLASS { &NULL } 89 90sub OWNER_SECURITY_INFORMATION { 0x00000001 } 91sub GROUP_SECURITY_INFORMATION { 0x00000002 } 92sub DACL_SECURITY_INFORMATION { 0x00000004 } 93sub SACL_SECURITY_INFORMATION { 0x00000008 } 94 95sub MB_ICONHAND { 0x00000010 } 96sub MB_ICONQUESTION { 0x00000020 } 97sub MB_ICONEXCLAMATION { 0x00000030 } 98sub MB_ICONASTERISK { 0x00000040 } 99sub MB_ICONWARNING { 0x00000030 } 100sub MB_ICONERROR { 0x00000010 } 101sub MB_ICONINFORMATION { 0x00000040 } 102sub MB_ICONSTOP { 0x00000010 } 103 104# 105# Newly added constants. These have an empty prototype, unlike the 106# the ones above, which aren't prototyped for compatibility reasons. 107# 108sub SW_HIDE () { 0 } 109sub SW_SHOWNORMAL () { 1 } 110sub SW_SHOWMINIMIZED () { 2 } 111sub SW_SHOWMAXIMIZED () { 3 } 112sub SW_SHOWNOACTIVATE () { 4 } 113 114sub CSIDL_DESKTOP () { 0x0000 } # <desktop> 115sub CSIDL_PROGRAMS () { 0x0002 } # Start Menu\Programs 116sub CSIDL_PERSONAL () { 0x0005 } # "My Documents" folder 117sub CSIDL_FAVORITES () { 0x0006 } # <user name>\Favorites 118sub CSIDL_STARTUP () { 0x0007 } # Start Menu\Programs\Startup 119sub CSIDL_RECENT () { 0x0008 } # <user name>\Recent 120sub CSIDL_SENDTO () { 0x0009 } # <user name>\SendTo 121sub CSIDL_STARTMENU () { 0x000B } # <user name>\Start Menu 122sub CSIDL_MYMUSIC () { 0x000D } # "My Music" folder 123sub CSIDL_MYVIDEO () { 0x000E } # "My Videos" folder 124sub CSIDL_DESKTOPDIRECTORY () { 0x0010 } # <user name>\Desktop 125sub CSIDL_NETHOOD () { 0x0013 } # <user name>\nethood 126sub CSIDL_FONTS () { 0x0014 } # windows\fonts 127sub CSIDL_TEMPLATES () { 0x0015 } 128sub CSIDL_COMMON_STARTMENU () { 0x0016 } # All Users\Start Menu 129sub CSIDL_COMMON_PROGRAMS () { 0x0017 } # All Users\Start Menu\Programs 130sub CSIDL_COMMON_STARTUP () { 0x0018 } # All Users\Startup 131sub CSIDL_COMMON_DESKTOPDIRECTORY () { 0x0019 } # All Users\Desktop 132sub CSIDL_APPDATA () { 0x001A } # Application Data, new for NT4 133sub CSIDL_PRINTHOOD () { 0x001B } # <user name>\PrintHood 134sub CSIDL_LOCAL_APPDATA () { 0x001C } # non roaming, user\Local Settings\Application Data 135sub CSIDL_COMMON_FAVORITES () { 0x001F } 136sub CSIDL_INTERNET_CACHE () { 0x0020 } 137sub CSIDL_COOKIES () { 0x0021 } 138sub CSIDL_HISTORY () { 0x0022 } 139sub CSIDL_COMMON_APPDATA () { 0x0023 } # All Users\Application Data 140sub CSIDL_WINDOWS () { 0x0024 } # GetWindowsDirectory() 141sub CSIDL_SYSTEM () { 0x0025 } # GetSystemDirectory() 142sub CSIDL_PROGRAM_FILES () { 0x0026 } # C:\Program Files 143sub CSIDL_MYPICTURES () { 0x0027 } # "My Pictures", new for Win2K 144sub CSIDL_PROFILE () { 0x0028 } # USERPROFILE 145sub CSIDL_PROGRAM_FILES_COMMON () { 0x002B } # C:\Program Files\Common 146sub CSIDL_COMMON_TEMPLATES () { 0x002D } # All Users\Templates 147sub CSIDL_COMMON_DOCUMENTS () { 0x002E } # All Users\Documents 148sub CSIDL_COMMON_ADMINTOOLS () { 0x002F } # All Users\Start Menu\Programs\Administrative Tools 149sub CSIDL_ADMINTOOLS () { 0x0030 } # <user name>\Start Menu\Programs\Administrative Tools 150sub CSIDL_COMMON_MUSIC () { 0x0035 } # All Users\My Music 151sub CSIDL_COMMON_PICTURES () { 0x0036 } # All Users\My Pictures 152sub CSIDL_COMMON_VIDEO () { 0x0037 } # All Users\My Video 153sub CSIDL_RESOURCES () { 0x0038 } # %windir%\Resources\, For theme and other windows resources. 154sub CSIDL_RESOURCES_LOCALIZED () { 0x0039 } # %windir%\Resources\<LangID>, for theme and other windows specific resources. 155sub CSIDL_CDBURN_AREA () { 0x003B } # <user name>\Local Settings\Application Data\Microsoft\CD Burning 156 157sub VER_NT_DOMAIN_CONTROLLER () { 0x0000002 } # The system is a domain controller and the operating system is Windows Server 2008, Windows Server 2003, or Windows 2000 Server. 158sub VER_NT_SERVER () { 0x0000003 } # The operating system is Windows Server 2008, Windows Server 2003, or Windows 2000 Server. 159# Note that a server that is also a domain controller is reported as VER_NT_DOMAIN_CONTROLLER, not VER_NT_SERVER. 160sub VER_NT_WORKSTATION () { 0x0000001 } # The operating system is Windows Vista, Windows XP Professional, Windows XP Home Edition, or Windows 2000 Professional. 161 162 163sub VER_SUITE_BACKOFFICE () { 0x00000004 } # Microsoft BackOffice components are installed. 164sub VER_SUITE_BLADE () { 0x00000400 } # Windows Server 2003, Web Edition is installed. 165sub VER_SUITE_COMPUTE_SERVER () { 0x00004000 } # Windows Server 2003, Compute Cluster Edition is installed. 166sub VER_SUITE_DATACENTER () { 0x00000080 } # Windows Server 2008 Datacenter, Windows Server 2003, Datacenter Edition, or Windows 2000 Datacenter Server is installed. 167sub VER_SUITE_ENTERPRISE () { 0x00000002 } # Windows Server 2008 Enterprise, Windows Server 2003, Enterprise Edition, or Windows 2000 Advanced Server is installed. Refer to the Remarks section for more information about this bit flag. 168sub VER_SUITE_EMBEDDEDNT () { 0x00000040 } # Windows XP Embedded is installed. 169sub VER_SUITE_PERSONAL () { 0x00000200 } # Windows Vista Home Premium, Windows Vista Home Basic, or Windows XP Home Edition is installed. 170sub VER_SUITE_SINGLEUSERTS () { 0x00000100 } # Remote Desktop is supported, but only one interactive session is supported. This value is set unless the system is running in application server mode. 171sub VER_SUITE_SMALLBUSINESS () { 0x00000001 } # Microsoft Small Business Server was once installed on the system, but may have been upgraded to another version of Windows. Refer to the Remarks section for more information about this bit flag. 172sub VER_SUITE_SMALLBUSINESS_RESTRICTED () { 0x00000020 } # Microsoft Small Business Server is installed with the restrictive client license in force. Refer to the Remarks section for more information about this bit flag. 173sub VER_SUITE_STORAGE_SERVER () { 0x00002000 } # Windows Storage Server 2003 R2 or Windows Storage Server 2003 is installed. 174sub VER_SUITE_TERMINAL () { 0x00000010 } # Terminal Services is installed. This value is always set. 175# If VER_SUITE_TERMINAL is set but VER_SUITE_SINGLEUSERTS is not set, the system is running in application server mode. 176sub VER_SUITE_WH_SERVER () { 0x00008000 } # Windows Home Server is installed. 177sub VER_SUITE_MULTIUSERTS () { 0x00020000 } # AppServer mode is enabled. 178 179 180sub SM_TABLETPC () { 86 } 181sub SM_MEDIACENTER () { 87 } 182sub SM_STARTER () { 88 } 183sub SM_SERVERR2 () { 89 } 184 185sub PRODUCT_UNDEFINED () { 0x000 } # An unknown product 186sub PRODUCT_ULTIMATE () { 0x001 } # Ultimate 187sub PRODUCT_HOME_BASIC () { 0x002 } # Home Basic 188sub PRODUCT_HOME_PREMIUM () { 0x003 } # Home Premium 189sub PRODUCT_ENTERPRISE () { 0x004 } # Enterprise 190sub PRODUCT_HOME_BASIC_N () { 0x005 } # Home Basic N 191sub PRODUCT_BUSINESS () { 0x006 } # Business 192sub PRODUCT_STANDARD_SERVER () { 0x007 } # Server Standard (full installation) 193sub PRODUCT_DATACENTER_SERVER () { 0x008 } # Server Datacenter (full installation) 194sub PRODUCT_SMALLBUSINESS_SERVER () { 0x009 } # Windows Small Business Server 195sub PRODUCT_ENTERPRISE_SERVER () { 0x00A } # Server Enterprise (full installation) 196sub PRODUCT_STARTER () { 0x00B } # Starter 197sub PRODUCT_DATACENTER_SERVER_CORE () { 0x00C } # Server Datacenter (core installation) 198sub PRODUCT_STANDARD_SERVER_CORE () { 0x00D } # Server Standard (core installation) 199sub PRODUCT_ENTERPRISE_SERVER_CORE () { 0x00E } # Server Enterprise (core installation) 200sub PRODUCT_ENTERPRISE_SERVER_IA64 () { 0x00F } # Server Enterprise for Itanium-based Systems 201sub PRODUCT_BUSINESS_N () { 0x010 } # Business N 202sub PRODUCT_WEB_SERVER () { 0x011 } # Web Server (full installation) 203sub PRODUCT_CLUSTER_SERVER () { 0x012 } # HPC Edition 204sub PRODUCT_HOME_SERVER () { 0x013 } # Home Server Edition 205sub PRODUCT_STORAGE_EXPRESS_SERVER () { 0x014 } # Storage Server Express 206sub PRODUCT_STORAGE_STANDARD_SERVER () { 0x015 } # Storage Server Standard 207sub PRODUCT_STORAGE_WORKGROUP_SERVER () { 0x016 } # Storage Server Workgroup 208sub PRODUCT_STORAGE_ENTERPRISE_SERVER () { 0x017 } # Storage Server Enterprise 209sub PRODUCT_SERVER_FOR_SMALLBUSINESS () { 0x018 } # Windows Server 2008 for Windows Essential Server Solutions 210sub PRODUCT_SMALLBUSINESS_SERVER_PREMIUM () { 0x019 } # Windows Small Business Server Premium 211sub PRODUCT_HOME_PREMIUM_N () { 0x01A } # Home Premium N 212sub PRODUCT_ENTERPRISE_N () { 0x01B } # Enterprise N 213sub PRODUCT_ULTIMATE_N () { 0x01C } # Ultimate N 214sub PRODUCT_WEB_SERVER_CORE () { 0x01D } # Web Server (core installation) 215sub PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT () { 0x01E } # Windows Essential Business Server Management Server 216sub PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY () { 0x01F } # Windows Essential Business Server Security Server 217sub PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING () { 0x020 } # Windows Essential Business Server Messaging Server 218sub PRODUCT_SERVER_FOUNDATION () { 0x021 } # Server Foundation 219#define PRODUCT_HOME_PREMIUM_SERVER 0x00000022 220sub PRODUCT_SERVER_FOR_SMALLBUSINESS_V () { 0x023 } # Windows Server 2008 without Hyper-V for Windows Essential Server Solutions 221sub PRODUCT_STANDARD_SERVER_V () { 0x024 } # Server Standard without Hyper-V (full installation) 222sub PRODUCT_DATACENTER_SERVER_V () { 0x025 } # Server Datacenter without Hyper-V (full installation) 223sub PRODUCT_ENTERPRISE_SERVER_V () { 0x026 } # Server Enterprise without Hyper-V (full installation) 224sub PRODUCT_DATACENTER_SERVER_CORE_V () { 0x027 } # Server Datacenter without Hyper-V (core installation) 225sub PRODUCT_STANDARD_SERVER_CORE_V () { 0x028 } # Server Standard without Hyper-V (core installation) 226sub PRODUCT_ENTERPRISE_SERVER_CORE_V () { 0x029 } # Server Enterprise without Hyper-V (core installation) 227sub PRODUCT_HYPERV () { 0x02A } # Microsoft Hyper-V Server 228#define PRODUCT_STORAGE_EXPRESS_SERVER_CORE 0x0000002B 229#define PRODUCT_STORAGE_STANDARD_SERVER_CORE 0x0000002C 230#define PRODUCT_STORAGE_WORKGROUP_SERVER_CORE 0x0000002D 231#define PRODUCT_STORAGE_ENTERPRISE_SERVER_CORE 0x0000002E 232sub PRODUCT_STARTER_N () { 0x02F } # Starter N 233sub PRODUCT_PROFESSIONAL () { 0x030 } # Professional 234sub PRODUCT_PROFESSIONAL_N () { 0x031 } # Professional N 235#define PRODUCT_SB_SOLUTION_SERVER 0x00000032 236#define PRODUCT_SERVER_FOR_SB_SOLUTIONS 0x00000033 237#define PRODUCT_STANDARD_SERVER_SOLUTIONS 0x00000034 238#define PRODUCT_STANDARD_SERVER_SOLUTIONS_CORE 0x00000035 239#define PRODUCT_SB_SOLUTION_SERVER_EM 0x00000036 240#define PRODUCT_SERVER_FOR_SB_SOLUTIONS_EM 0x00000037 241#define PRODUCT_SOLUTION_EMBEDDEDSERVER 0x00000038 242#define PRODUCT_SOLUTION_EMBEDDEDSERVER_CORE 0x00000039 243#define PRODUCT_PROFESSIONAL_EMBEDDED 0x0000003A 244#define PRODUCT_ESSENTIALBUSINESS_SERVER_MGMT 0x0000003B 245#define PRODUCT_ESSENTIALBUSINESS_SERVER_ADDL 0x0000003C 246#define PRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC 0x0000003D 247#define PRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC 0x0000003E 248#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE 0x0000003F 249#define PRODUCT_CLUSTER_SERVER_V 0x00000040 250#define PRODUCT_EMBEDDED 0x00000041 251sub PRODUCT_STARTER_E () { 0x042 } # Starter E 252sub PRODUCT_HOME_BASIC_E () { 0x043 } # Home Basic E 253sub PRODUCT_HOME_PREMIUM_E () { 0x044 } # Home Premium E 254sub PRODUCT_PROFESSIONAL_E () { 0x045 } # Professional E 255sub PRODUCT_ENTERPRISE_E () { 0x046 } # Enterprise E 256sub PRODUCT_ULTIMATE_E () { 0x047 } # Ultimate E 257#define PRODUCT_ENTERPRISE_EVALUATION 0x00000048 258#define PRODUCT_MULTIPOINT_STANDARD_SERVER 0x0000004C 259#define PRODUCT_MULTIPOINT_PREMIUM_SERVER 0x0000004D 260#define PRODUCT_STANDARD_EVALUATION_SERVER 0x0000004F 261#define PRODUCT_DATACENTER_EVALUATION_SERVER 0x00000050 262#define PRODUCT_ENTERPRISE_N_EVALUATION 0x00000054 263#define PRODUCT_EMBEDDED_AUTOMOTIVE 0x00000055 264#define PRODUCT_EMBEDDED_INDUSTRY_A 0x00000056 265#define PRODUCT_THINPC 0x00000057 266#define PRODUCT_EMBEDDED_A 0x00000058 267#define PRODUCT_EMBEDDED_INDUSTRY 0x00000059 268#define PRODUCT_EMBEDDED_E 0x0000005A 269#define PRODUCT_EMBEDDED_INDUSTRY_E 0x0000005B 270#define PRODUCT_EMBEDDED_INDUSTRY_A_E 0x0000005C 271#define PRODUCT_STORAGE_WORKGROUP_EVALUATION_SERVER 0x0000005F 272#define PRODUCT_STORAGE_STANDARD_EVALUATION_SERVER 0x00000060 273#define PRODUCT_CORE_ARM 0x00000061 274sub PRODUCT_CORE_N () { 0x62 } # Windows 10 Home N 275sub PRODUCT_CORE_COUNTRYSPECIFIC () { 0x63 } # Windows 10 Home China 276sub PRODUCT_CORE_SINGLELANGUAGE () { 0x64 } # Windows 10 Home Single Language 277sub PRODUCT_CORE () { 0x65 } # Windows 10 Home 278#define PRODUCT_PROFESSIONAL_WMC 0x00000067 279#define PRODUCT_MOBILE_CORE 0x00000068 280#define PRODUCT_EMBEDDED_INDUSTRY_EVAL 0x00000069 281#define PRODUCT_EMBEDDED_INDUSTRY_E_EVAL 0x0000006A 282#define PRODUCT_EMBEDDED_EVAL 0x0000006B 283#define PRODUCT_EMBEDDED_E_EVAL 0x0000006C 284#define PRODUCT_NANO_SERVER 0x0000006D 285#define PRODUCT_CLOUD_STORAGE_SERVER 0x0000006E 286#define PRODUCT_CORE_CONNECTED 0x0000006F 287#define PRODUCT_PROFESSIONAL_STUDENT 0x00000070 288#define PRODUCT_CORE_CONNECTED_N 0x00000071 289#define PRODUCT_PROFESSIONAL_STUDENT_N 0x00000072 290#define PRODUCT_CORE_CONNECTED_SINGLELANGUAGE 0x00000073 291#define PRODUCT_CORE_CONNECTED_COUNTRYSPECIFIC 0x00000074 292#define PRODUCT_CONNECTED_CAR 0x00000075 293#define PRODUCT_INDUSTRY_HANDHELD 0x00000076 294#define PRODUCT_PPI_PRO 0x00000077 295#define PRODUCT_ARM64_SERVER 0x00000078 296sub PRODUCT_EDUCATION () { 0x79 } # Windows 10 Education 297sub PRODUCT_EDUCATION_N () { 0x7A } # Windows 10 Education N 298#define PRODUCT_IOTUAP 0x0000007B 299#define PRODUCT_CLOUD_HOST_INFRASTRUCTURE_SERVER 0x0000007C 300#define PRODUCT_ENTERPRISE_S 0x0000007D 301#define PRODUCT_ENTERPRISE_S_N 0x0000007E 302#define PRODUCT_PROFESSIONAL_S 0x0000007F 303#define PRODUCT_PROFESSIONAL_S_N 0x00000080 304#define PRODUCT_ENTERPRISE_S_EVALUATION 0x00000081 305#define PRODUCT_ENTERPRISE_S_N_EVALUATION 0x00000082 306 307sub PRODUCT_UNLICENSED () { 0xABCDABCD } # product has not been activated and is no longer in the grace period 308 309sub PROCESSOR_ARCHITECTURE_ARM64 () { 12 } # ARM64 310sub PROCESSOR_ARCHITECTURE_ARM () { 5 } # ARM 311sub PROCESSOR_ARCHITECTURE_AMD64 () { 9 } # x64 (AMD or Intel) 312sub PROCESSOR_ARCHITECTURE_IA64 () { 6 } # Intel Itanium Processor Family (IPF) 313sub PROCESSOR_ARCHITECTURE_INTEL () { 0 } # x86 314sub PROCESSOR_ARCHITECTURE_UNKNOWN () { 0xffff } # Unknown architecture. 315 316sub _GetProcessorArchitecture { 317 my $arch = { 318 386 => PROCESSOR_ARCHITECTURE_INTEL, 319 486 => PROCESSOR_ARCHITECTURE_INTEL, 320 586 => PROCESSOR_ARCHITECTURE_INTEL, 321 2200 => PROCESSOR_ARCHITECTURE_IA64, 322 8664 => PROCESSOR_ARCHITECTURE_AMD64, 323 }->{Win32::GetChipName()}; 324 325 if (!defined($arch)) { 326 $arch = { 327 5 => PROCESSOR_ARCHITECTURE_ARM, 328 12 => PROCESSOR_ARCHITECTURE_ARM64, 329 }->{Win32::GetChipArch()}; 330 } 331 332 return defined($arch) ? $arch : PROCESSOR_ARCHITECTURE_UNKNOWN; 333} 334 335### This method is just a simple interface into GetOSVersion(). More 336### specific or demanding situations should use that instead. 337 338my ($cached_os, $cached_desc); 339 340sub GetOSName { 341 unless (defined $cached_os) { 342 my($desc, $major, $minor, $build, $id, undef, undef, $suitemask, $producttype) 343 = Win32::GetOSVersion(); 344 my $arch = _GetProcessorArchitecture(); 345 my $productinfo = Win32::GetProductInfo(6, 0, 0, 0); 346 ($cached_os, $cached_desc) = _GetOSName($desc, $major, $minor, $build, $id, 347 $suitemask, $producttype, $productinfo, $arch); 348 } 349 return wantarray ? ($cached_os, $cached_desc) : $cached_os; 350} 351 352sub GetOSDisplayName { 353 # Calling GetOSDisplayName() with arguments is for the test suite only! 354 my($name,$desc) = @_ ? @_ : GetOSName(); 355 $name =~ s/^Win//; 356 if ($desc =~ /^Windows Home Server\b/ || $desc =~ /^Windows XP Professional x64 Edition\b/) { 357 ($name, $desc) = ($desc, ""); 358 } 359 elsif ($desc =~ s/\s*(Windows (.*) Server( \d+)?)//) { 360 $name = "$1 $name"; 361 $desc =~ s/^\s+//; 362 } 363 else { 364 for ($name) { 365 s/^/Windows / unless /^Win32s$/; 366 s/\/.Net//; 367 s/NT(\d)/NT $1/; 368 if ($desc =~ s/\s*(HPC|Small Business|Web) Server//) { 369 my $name = $1; 370 $desc =~ s/^\s*//; 371 s/(200.)/$name Server $1/; 372 } 373 s/^Windows (20(03|08|12|16|19))/Windows Server $1/; 374 s/^Windows SAC/Windows Server/; 375 } 376 } 377 $name .= " $desc" if length $desc; 378 return $name; 379} 380 381sub _GetSystemMetrics { 382 my($index,$metrics) = @_; 383 return Win32::GetSystemMetrics($index) unless ref $metrics; 384 return $metrics->{$index} if ref $metrics eq "HASH" && defined $metrics->{$index}; 385 return 1 if ref $metrics eq "ARRAY" && grep $_ == $index, @$metrics; 386 return 0; 387} 388 389sub _GetOSName { 390 # The $metrics argument only exists for the benefit of t/GetOSName.t 391 my($csd, $major, $minor, $build, $id, $suitemask, $producttype, $productinfo, $arch, $metrics) = @_; 392 393 my($os,@tags); 394 my $desc = ""; 395 if ($id == 0) { 396 $os = "Win32s"; 397 } 398 elsif ($id == 1) { 399 if ($minor == 0) { 400 $os = "95"; 401 } 402 elsif ($minor == 10) { 403 $os = "98"; 404 } 405 elsif ($minor == 90) { 406 $os = "Me"; 407 } 408 } 409 elsif ($id == 2) { 410 if ($major == 3) { 411 $os = "NT3.51"; 412 } 413 elsif ($major == 4) { 414 $os = "NT4"; 415 } 416 elsif ($major == 5) { 417 if ($minor == 0) { 418 $os = "2000"; 419 if ($producttype == VER_NT_WORKSTATION) { 420 $desc = "Professional"; 421 } 422 else { 423 if ($suitemask & VER_SUITE_DATACENTER) { 424 $desc = "Datacenter Server"; 425 } 426 elsif ($suitemask & VER_SUITE_ENTERPRISE) { 427 $desc = "Advanced Server"; 428 } 429 elsif ($suitemask & VER_SUITE_SMALLBUSINESS_RESTRICTED) { 430 $desc = "Small Business Server"; 431 } 432 else { 433 $desc = "Server"; 434 } 435 } 436 # XXX ignoring "Windows 2000 Advanced Server Limited Edition" for Itanium 437 # XXX and "Windows 2000 Datacenter Server Limited Edition" for Itanium 438 } 439 elsif ($minor == 1) { 440 $os = "XP/.Net"; 441 if (_GetSystemMetrics(SM_MEDIACENTER, $metrics)) { 442 $desc = "Media Center Edition"; 443 } 444 elsif (_GetSystemMetrics(SM_TABLETPC, $metrics)) { 445 # Tablet PC Edition is based on XP Pro 446 $desc = "Tablet PC Edition"; 447 } 448 elsif (_GetSystemMetrics(SM_STARTER, $metrics)) { 449 $desc = "Starter Edition"; 450 } 451 elsif ($suitemask & VER_SUITE_PERSONAL) { 452 $desc = "Home Edition"; 453 } 454 else { 455 $desc = "Professional"; 456 } 457 # XXX ignoring all Windows XP Embedded and Fundamentals versions 458 } 459 elsif ($minor == 2) { 460 $os = "2003"; 461 462 if (_GetSystemMetrics(SM_SERVERR2, $metrics)) { 463 # XXX R2 was released for all x86 and x64 versions, 464 # XXX but only Enterprise Edition for Itanium. 465 $desc = "R2"; 466 } 467 468 if ($suitemask == VER_SUITE_STORAGE_SERVER) { 469 $desc .= " Windows Storage Server"; 470 } 471 elsif ($suitemask == VER_SUITE_WH_SERVER) { 472 $desc .= " Windows Home Server"; 473 } 474 elsif ($producttype == VER_NT_WORKSTATION && $arch == PROCESSOR_ARCHITECTURE_AMD64) { 475 $desc .= " Windows XP Professional x64 Edition"; 476 } 477 478 # Test for the server type. 479 if ($producttype != VER_NT_WORKSTATION) { 480 if ($arch == PROCESSOR_ARCHITECTURE_IA64) { 481 if ($suitemask & VER_SUITE_DATACENTER) { 482 $desc .= " Datacenter Edition for Itanium-based Systems"; 483 } 484 elsif ($suitemask & VER_SUITE_ENTERPRISE) { 485 $desc .= " Enterprise Edition for Itanium-based Systems"; 486 } 487 } 488 elsif ($arch == PROCESSOR_ARCHITECTURE_AMD64) { 489 if ($suitemask & VER_SUITE_DATACENTER) { 490 $desc .= " Datacenter x64 Edition"; 491 } 492 elsif ($suitemask & VER_SUITE_ENTERPRISE) { 493 $desc .= " Enterprise x64 Edition"; 494 } 495 else { 496 $desc .= " Standard x64 Edition"; 497 } 498 } 499 else { 500 if ($suitemask & VER_SUITE_COMPUTE_SERVER) { 501 $desc .= " Windows Compute Cluster Server"; 502 } 503 elsif ($suitemask & VER_SUITE_DATACENTER) { 504 $desc .= " Datacenter Edition"; 505 } 506 elsif ($suitemask & VER_SUITE_ENTERPRISE) { 507 $desc .= " Enterprise Edition"; 508 } 509 elsif ($suitemask & VER_SUITE_BLADE) { 510 $desc .= " Web Edition"; 511 } 512 elsif ($suitemask & VER_SUITE_SMALLBUSINESS_RESTRICTED) { 513 $desc .= " Small Business Server"; 514 } 515 else { 516 if ($desc !~ /Windows (Home|Storage) Server/) { 517 $desc .= " Standard Edition"; 518 } 519 } 520 } 521 } 522 } 523 } 524 elsif ($major == 6) { 525 if ($minor == 0) { 526 if ($producttype == VER_NT_WORKSTATION) { 527 $os = "Vista"; 528 } 529 else { 530 $os = "2008"; 531 } 532 } 533 elsif ($minor == 1) { 534 if ($producttype == VER_NT_WORKSTATION) { 535 $os = "7"; 536 } 537 else { 538 $os = "2008"; 539 $desc = "R2"; 540 } 541 } 542 elsif ($minor == 2) { 543 if ($producttype == VER_NT_WORKSTATION) { 544 $os = "8"; 545 } 546 else { 547 $os = "2012"; 548 } 549 } 550 elsif ($minor == 3) { 551 if ($producttype == VER_NT_WORKSTATION) { 552 $os = "8.1"; 553 } 554 else { 555 $os = "2012"; 556 $desc = "R2"; 557 } 558 } 559 } 560 elsif ($major == 10) { 561 if ($producttype == VER_NT_WORKSTATION) { 562 # Build numbers from https://en.wikipedia.org/wiki/Windows_10_version_history 563 $os = '10'; 564 if (9841 <= $build && $build <= 10240) { 565 $desc = " Version 1507"; 566 $desc .= " (Preview Build $build)" if $build < 10240; 567 $desc .= " (RTM)" if $build == 10240; 568 } 569 elsif (10525 <= $build && $build <= 10586) { 570 $desc = " Version 1511 (November Update)"; 571 $desc .= " (Preview Build $build)" if $build < 10586; 572 } 573 elsif (11082 <= $build && $build <= 14393) { 574 $desc = " Version 1607 (Anniversary Update)"; 575 $desc .= " (Preview Build $build)" if $build < 14393; 576 } 577 elsif (14901 <= $build && $build <= 15063) { 578 $desc = " Version 1703 (Creators Update)"; 579 $desc .= " (Preview Build $build)" if $build < 15063; 580 } 581 elsif (16170 <= $build && $build <= 16299) { 582 $desc = " Version 1709 (Fall Creators Update)"; 583 $desc .= " (Preview Build $build)" if $build < 16299; 584 } 585 elsif (16353 <= $build && $build <= 17134) { 586 $desc = " Version 1803 (April 2018 Update)"; 587 $desc .= " (Preview Build $build)" if $build < 17134; 588 } 589 elsif (17604 <= $build && $build <= 17763) { 590 $desc = " Version 1809 (October 2018 Update)"; 591 $desc .= " (Preview Build $build)" if $build < 17763; 592 } 593 elsif (18204 <= $build && $build <= 18362) { 594 $desc = " Version 1903 (May 2019 Update)"; 595 $desc .= " (Preview Build $build)" if $build < 18362; 596 } 597 else { 598 $desc = " Build $build"; 599 } 600 } 601 else { 602 if ($build == 14393) { 603 $os = "2016"; 604 $desc = "Version 1607"; 605 } 606 elsif ($build == 17763) { 607 $os = "2019"; 608 $desc = "Version 1809"; 609 } 610 else { 611 $os = "Server"; 612 if ($build == 16299) { 613 $desc = "Version 1709"; 614 } 615 elsif ($build == 17134) { 616 $desc = "Version 1803"; 617 } 618 elsif ($build == 18362) { 619 $desc = "Version 1903"; 620 } 621 else { 622 $desc = "Build $build"; 623 } 624 } 625 } 626 } 627 628 if ($major >= 6) { 629 if ($major == 6) { 630 if ($productinfo == PRODUCT_ULTIMATE) { 631 $desc .= " Ultimate"; 632 } 633 elsif ($productinfo == PRODUCT_HOME_PREMIUM) { 634 $desc .= " Home Premium"; 635 } 636 elsif ($productinfo == PRODUCT_HOME_BASIC) { 637 $desc .= " Home Basic"; 638 } 639 elsif ($productinfo == PRODUCT_ENTERPRISE) { 640 $desc .= " Enterprise"; 641 } 642 elsif ($productinfo == PRODUCT_BUSINESS) { 643 # "Windows 7 Business" had a name change to "Windows 7 Professional" 644 $desc .= $minor == 0 ? " Business" : " Professional"; 645 } 646 elsif ($productinfo == PRODUCT_STARTER) { 647 $desc .= " Starter"; 648 } 649 elsif ($productinfo == PRODUCT_CLUSTER_SERVER) { 650 $desc .= " HPC Server"; 651 } 652 elsif ($productinfo == PRODUCT_DATACENTER_SERVER) { 653 $desc .= " Datacenter"; 654 } 655 elsif ($productinfo == PRODUCT_DATACENTER_SERVER_CORE) { 656 $desc .= " Datacenter Edition (core installation)"; 657 } 658 elsif ($productinfo == PRODUCT_ENTERPRISE_SERVER) { 659 $desc .= " Enterprise"; 660 } 661 elsif ($productinfo == PRODUCT_ENTERPRISE_SERVER_CORE) { 662 $desc .= " Enterprise Edition (core installation)"; 663 } 664 elsif ($productinfo == PRODUCT_ENTERPRISE_SERVER_IA64) { 665 $desc .= " Enterprise Edition for Itanium-based Systems"; 666 } 667 elsif ($productinfo == PRODUCT_SMALLBUSINESS_SERVER) { 668 $desc .= " Small Business Server"; 669 } 670 elsif ($productinfo == PRODUCT_SMALLBUSINESS_SERVER_PREMIUM) { 671 $desc .= " Small Business Server Premium Edition"; 672 } 673 elsif ($productinfo == PRODUCT_STANDARD_SERVER) { 674 $desc .= " Standard"; 675 } 676 elsif ($productinfo == PRODUCT_STANDARD_SERVER_CORE) { 677 $desc .= " Standard Edition (core installation)"; 678 } 679 elsif ($productinfo == PRODUCT_WEB_SERVER) { 680 $desc .= " Web Server"; 681 } 682 elsif ($productinfo == PRODUCT_PROFESSIONAL) { 683 $desc .= " Professional"; 684 } 685 } 686 687 if ($arch == PROCESSOR_ARCHITECTURE_INTEL) { 688 $desc .= " (32-bit)"; 689 } 690 elsif ($arch == PROCESSOR_ARCHITECTURE_AMD64) { 691 $desc .= " (64-bit)"; 692 } 693 } 694 } 695 696 unless (defined $os) { 697 warn "Unknown Windows version [$id:$major:$minor]"; 698 return; 699 } 700 701 for ($desc) { 702 s/\s\s+/ /g; 703 s/^\s//; 704 s/\s$//; 705 } 706 707 # XXX What about "Small Business Server"? NT, 200, 2003, 2008 editions... 708 709 if ($major >= 5) { 710 # XXX XP, Vista, 7 all have starter editions 711 #push(@tags, "Starter Edition") if _GetSystemMetrics(SM_STARTER, $metrics); 712 } 713 714 if (@tags) { 715 unshift(@tags, $desc) if length $desc; 716 $desc = join(" ", @tags); 717 } 718 719 if (length $csd) { 720 $desc .= " " if length $desc; 721 $desc .= $csd; 722 } 723 return ("Win$os", $desc); 724} 725 726sub IsSymlinkCreationAllowed { 727 my(undef, $major, $minor, $build) = GetOSVersion(); 728 729 # Vista was the first Windows version with symlink support 730 return !!0 if $major < 6; 731 732 # Since Windows 10 1703, enabling the developer mode allows to create 733 # symlinks regardless of process privileges 734 if ($major > 10 || ($major == 10 && ($minor > 0 || $build > 15063))) { 735 return !!1 if IsDeveloperModeEnabled(); 736 } 737 738 my $privs = GetProcessPrivileges(); 739 740 return !!0 unless $privs; 741 742 # It doesn't matter if the permission is enabled or not, it just has to 743 # exist. CreateSymbolicLink() will automatically enable it when needed. 744 return exists $privs->{SeCreateSymbolicLinkPrivilege}; 745} 746 747# "no warnings 'redefine';" doesn't work for 5.8.7 and earlier 748local $^W = 0; 749bootstrap Win32; 750 7511; 752 753__END__ 754 755=head1 NAME 756 757Win32 - Interfaces to some Win32 API Functions 758 759=head1 DESCRIPTION 760 761The Win32 module contains functions to access Win32 APIs. 762 763=head2 Alphabetical Listing of Win32 Functions 764 765It is recommended to C<use Win32;> before any of these functions; 766however, for backwards compatibility, those marked as [CORE] will 767automatically do this for you. 768 769In the function descriptions below the term I<Unicode string> is used 770to indicate that the string may contain characters outside the system 771codepage. The caveat I<If supported by the core Perl version> 772generally means Perl 5.8.9 and later, though some Unicode pathname 773functionality may work on earlier versions. 774 775=over 776 777=item Win32::AbortSystemShutdown(MACHINE) 778 779Aborts a system shutdown (started by the 780InitiateSystemShutdown function) on the specified MACHINE. 781 782=item Win32::BuildNumber() 783 784[CORE] Returns the ActivePerl build number. This function is 785only available in the ActivePerl binary distribution. 786 787=item Win32::CopyFile(FROM, TO, OVERWRITE) 788 789[CORE] The Win32::CopyFile() function copies an existing file to a new 790file. All file information like creation time and file attributes will 791be copied to the new file. However it will B<not> copy the security 792information. If the destination file already exists it will only be 793overwritten when the OVERWRITE parameter is true. But even this will 794not overwrite a read-only file; you have to unlink() it first 795yourself. 796 797=item Win32::CreateDirectory(DIRECTORY) 798 799Creates the DIRECTORY and returns a true value on success. Check $^E 800on failure for extended error information. 801 802DIRECTORY may contain Unicode characters outside the system codepage. 803Once the directory has been created you can use 804Win32::GetANSIPathName() to get a name that can be passed to system 805calls and external programs. 806 807=item Win32::CreateFile(FILE) 808 809Creates the FILE and returns a true value on success. Check $^E on 810failure for extended error information. 811 812FILE may contain Unicode characters outside the system codepage. Once 813the file has been created you can use Win32::GetANSIPathName() to get 814a name that can be passed to system calls and external programs. 815 816=item Win32::DomainName() 817 818[CORE] Returns the name of the Microsoft Network domain or workgroup 819that the owner of the current perl process is logged into. The 820"Workstation" service must be running to determine this 821information. This function does B<not> work on Windows 9x. 822 823=item Win32::ExpandEnvironmentStrings(STRING) 824 825Takes STRING and replaces all referenced environment variable 826names with their defined values. References to environment variables 827take the form C<%VariableName%>. Case is ignored when looking up the 828VariableName in the environment. If the variable is not found then the 829original C<%VariableName%> text is retained. Has the same effect 830as the following: 831 832 $string =~ s/%([^%]*)%/$ENV{$1} || "%$1%"/eg 833 834However, this function may return a Unicode string if the environment 835variable being expanded hasn't been assigned to via %ENV. Access 836to %ENV is currently always using byte semantics. 837 838=item Win32::FormatMessage(ERRORCODE) 839 840[CORE] Converts the supplied Win32 error number (e.g. returned by 841Win32::GetLastError()) to a descriptive string. Analogous to the 842perror() standard-C library function. Note that C<$^E> used 843in a string context has much the same effect. 844 845 C:\> perl -e "$^E = 26; print $^E;" 846 The specified disk or diskette cannot be accessed 847 848=item Win32::FsType() 849 850[CORE] Returns the name of the filesystem of the currently active 851drive (like 'FAT' or 'NTFS'). In list context it returns three values: 852(FSTYPE, FLAGS, MAXCOMPLEN). FSTYPE is the filesystem type as 853before. FLAGS is a combination of values of the following table: 854 855 0x00000001 supports case-sensitive filenames 856 0x00000002 preserves the case of filenames 857 0x00000004 supports Unicode in filenames 858 0x00000008 preserves and enforces ACLs 859 0x00000010 supports file-based compression 860 0x00000020 supports disk quotas 861 0x00000040 supports sparse files 862 0x00000080 supports reparse points 863 0x00000100 supports remote storage 864 0x00008000 is a compressed volume (e.g. DoubleSpace) 865 0x00010000 supports object identifiers 866 0x00020000 supports the Encrypted File System (EFS) 867 868MAXCOMPLEN is the maximum length of a filename component (the part 869between two backslashes) on this file system. 870 871=item Win32::FreeLibrary(HANDLE) 872 873Unloads a previously loaded dynamic-link library. The HANDLE is 874no longer valid after this call. See L<LoadLibrary|Win32::LoadLibrary(LIBNAME)> 875for information on dynamically loading a library. 876 877=item Win32::GetACP() 878 879Returns the current Windows ANSI code page identifier for the operating 880system. See also GetOEMCP(), GetConsoleCP() and GetConsoleOutputCP(). 881 882=item Win32::GetANSIPathName(FILENAME) 883 884Returns an ANSI version of FILENAME. This may be the short name 885if the long name cannot be represented in the system codepage. 886 887While not currently implemented, it is possible that in the future 888this function will convert only parts of the path to FILENAME to a 889short form. 890 891If FILENAME doesn't exist on the filesystem, or if the filesystem 892doesn't support short ANSI filenames, then this function will 893translate the Unicode name into the system codepage using replacement 894characters. 895 896=item Win32::GetArchName() 897 898Use of this function is deprecated. It is equivalent with 899$ENV{PROCESSOR_ARCHITECTURE}. This might not work on Win9X. 900 901=item Win32::GetChipName() 902 903Returns the processor type: 386, 486 or 586 for x86 processors, 8664 for the x64 904processor and 2200 for the Itanium. For arm/arm64 processor, the value is marked 905as "Reserved" (not specified, but usually 0) in Microsoft documentation, so it's 906better to use GetChipArch(). Since it returns the native processor type it will 907return a 64-bit processor type even when called from a 32-bit Perl running on 90864-bit Windows. 909 910=item Win32::GetChipArch() 911 912Returns the processor architecture: 0 for x86 processors, 5 for arm, 6 for 913Itanium, 9 for x64 and 12 for arm64, and 0xFFFF for unknown architecture. 914 915=item Win32::GetConsoleCP() 916 917Returns the input code page used by the console associated with the 918calling process. To set the console's input code page, see 919SetConsoleCP(). See also GetConsoleOutputCP(), GetACP() and 920GetOEMCP(). 921 922=item Win32::GetConsoleOutputCP() 923 924Returns the output code page used by the console associated with the 925calling process. To set the console's output code page, see 926SetConsoleOutputCP(). See also GetConsoleCP(), GetACP(), and 927GetOEMCP(). 928 929=item Win32::GetCwd() 930 931[CORE] Returns the current active drive and directory. This function 932does not return a UNC path, since the functionality required for such 933a feature is not available under Windows 95. 934 935If supported by the core Perl version, this function will return an 936ANSI path name for the current directory if the long pathname cannot 937be represented in the system codepage. 938 939=item Win32::GetCurrentProcessId() 940 941Returns the process identifier of the current process. Until the 942process terminates, the process identifier uniquely identifies the 943process throughout the system. 944 945The current process identifier is normally also available via the 946predefined $$ variable. Under fork() emulation however $$ may contain 947a pseudo-process identifier that is only meaningful to the Perl 948kill(), wait() and waitpid() functions. The 949Win32::GetCurrentProcessId() function will always return the regular 950Windows process id, even when called from inside a pseudo-process. 951 952=item Win32::GetCurrentThreadId() 953 954Returns the thread identifier of the calling thread. Until the thread 955terminates, the thread identifier uniquely identifies the thread 956throughout the system. 957 958=item Win32::GetFileVersion(FILENAME) 959 960Returns the file version number from the VERSIONINFO resource of 961the executable file or DLL. This is a tuple of four 16 bit numbers. 962In list context these four numbers will be returned. In scalar context 963they are concatenated into a string, separated by dots. 964 965=item Win32::GetFolderPath(FOLDER [, CREATE]) 966 967Returns the full pathname of one of the Windows special folders. 968The folder will be created if it doesn't exist and the optional CREATE 969argument is true. The following FOLDER constants are defined by the 970Win32 module, but only exported on demand: 971 972 CSIDL_ADMINTOOLS 973 CSIDL_APPDATA 974 CSIDL_CDBURN_AREA 975 CSIDL_COMMON_ADMINTOOLS 976 CSIDL_COMMON_APPDATA 977 CSIDL_COMMON_DESKTOPDIRECTORY 978 CSIDL_COMMON_DOCUMENTS 979 CSIDL_COMMON_FAVORITES 980 CSIDL_COMMON_MUSIC 981 CSIDL_COMMON_PICTURES 982 CSIDL_COMMON_PROGRAMS 983 CSIDL_COMMON_STARTMENU 984 CSIDL_COMMON_STARTUP 985 CSIDL_COMMON_TEMPLATES 986 CSIDL_COMMON_VIDEO 987 CSIDL_COOKIES 988 CSIDL_DESKTOP 989 CSIDL_DESKTOPDIRECTORY 990 CSIDL_FAVORITES 991 CSIDL_FONTS 992 CSIDL_HISTORY 993 CSIDL_INTERNET_CACHE 994 CSIDL_LOCAL_APPDATA 995 CSIDL_MYMUSIC 996 CSIDL_MYPICTURES 997 CSIDL_MYVIDEO 998 CSIDL_NETHOOD 999 CSIDL_PERSONAL 1000 CSIDL_PRINTHOOD 1001 CSIDL_PROFILE 1002 CSIDL_PROGRAMS 1003 CSIDL_PROGRAM_FILES 1004 CSIDL_PROGRAM_FILES_COMMON 1005 CSIDL_RECENT 1006 CSIDL_RESOURCES 1007 CSIDL_RESOURCES_LOCALIZED 1008 CSIDL_SENDTO 1009 CSIDL_STARTMENU 1010 CSIDL_STARTUP 1011 CSIDL_SYSTEM 1012 CSIDL_TEMPLATES 1013 CSIDL_WINDOWS 1014 1015Note that not all folders are defined on all versions of Windows. 1016 1017Please refer to the MSDN documentation of the CSIDL constants, 1018currently available at: 1019 1020http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/enums/csidl.asp 1021 1022This function will return an ANSI folder path if the long name cannot 1023be represented in the system codepage. Use Win32::GetLongPathName() 1024on the result of Win32::GetFolderPath() if you want the Unicode 1025version of the folder name. 1026 1027=item Win32::GetFullPathName(FILENAME) 1028 1029[CORE] GetFullPathName combines the FILENAME with the current drive 1030and directory name and returns a fully qualified (aka, absolute) 1031path name. In list context it returns two elements: (PATH, FILE) where 1032PATH is the complete pathname component (including trailing backslash) 1033and FILE is just the filename part. Note that no attempt is made to 1034convert 8.3 components in the supplied FILENAME to longnames or 1035vice-versa. Compare with Win32::GetShortPathName() and 1036Win32::GetLongPathName(). 1037 1038If supported by the core Perl version, this function will return an 1039ANSI path name if the full pathname cannot be represented in the 1040system codepage. 1041 1042=item Win32::GetLastError() 1043 1044[CORE] Returns the last error value generated by a call to a Win32 API 1045function. Note that C<$^E> used in a numeric context amounts to the 1046same value. 1047 1048=item Win32::GetLongPathName(PATHNAME) 1049 1050[CORE] Returns a representation of PATHNAME composed of longname 1051components (if any). The result may not necessarily be longer 1052than PATHNAME. No attempt is made to convert PATHNAME to the 1053absolute path. Compare with Win32::GetShortPathName() and 1054Win32::GetFullPathName(). 1055 1056This function may return the pathname in Unicode if it cannot be 1057represented in the system codepage. Use Win32::GetANSIPathName() 1058before passing the path to a system call or another program. 1059 1060=item Win32::GetNextAvailDrive() 1061 1062[CORE] Returns a string in the form of "<d>:" where <d> is the first 1063available drive letter. 1064 1065=item Win32::GetOEMCP() 1066 1067Returns the current original equipment manufacturer (OEM) code page 1068identifier for the operating system. See also GetACP(), GetConsoleCP() 1069and GetConsoleOutputCP(). 1070 1071=item Win32::GetOSDisplayName() 1072 1073Returns the "marketing" name of the Windows operating system version 1074being used. It returns names like these (random samples): 1075 1076 Windows 2000 Datacenter Server 1077 Windows XP Professional 1078 Windows XP Tablet PC Edition 1079 Windows Home Server 1080 Windows Server 2003 Enterprise Edition for Itanium-based Systems 1081 Windows Vista Ultimate (32-bit) 1082 Windows Small Business Server 2008 R2 (64-bit) 1083 1084The display name describes the native Windows version, so even on a 108532-bit Perl this function may return a "Windows ... (64-bit)" name 1086when running on a 64-bit Windows. 1087 1088This function should only be used to display the actual OS name to the 1089user; it should not be used to determine the class of operating systems 1090this system belongs to. The Win32::GetOSName(), Win32::GetOSVersion, 1091Win32::GetProductInfo() and Win32::GetSystemMetrics() functions provide 1092the base information to check for certain capabilities, or for families 1093of OS releases. 1094 1095=item Win32::GetOSName() 1096 1097In scalar context returns the name of the Win32 operating system 1098being used. In list context returns a two element list of the OS name 1099and whatever edition information is known about the particular build 1100(for Win9X boxes) and whatever service packs have been installed. 1101The latter is roughly equivalent to the first item returned by 1102GetOSVersion() in list context. 1103 1104The description will also include tags for other special editions, 1105like "R2", "Media Center", "Tablet PC", or "Starter Edition". 1106 1107In the Windows 10 / Server Semi-Annual Channel era, the description may 1108contain the relevant ReleaseId value, but this is only inferred from 1109the build number, not determined absolutely. 1110 1111Currently the possible values for the OS name are 1112 1113 WinWin32s 1114 Win95 1115 Win98 1116 WinMe 1117 WinNT3.51 1118 WinNT4 1119 Win2000 1120 WinXP/.Net 1121 Win2003 1122 WinHomeSvr 1123 WinVista 1124 Win2008 1125 Win7 1126 Win8 1127 Win8.1 1128 Win10 1129 Win2016 1130 Win2019 1131 WinSAC 1132 1133This routine is just a simple interface into GetOSVersion(). More 1134specific or demanding situations should use that instead. Another 1135option would be to use POSIX::uname(), however the latter appears to 1136report only the OS family name and not the specific OS. In scalar 1137context it returns just the ID. 1138 1139The name "WinXP/.Net" is used for historical reasons only, to maintain 1140backwards compatibility of the Win32 module. Windows .NET Server has 1141been renamed as Windows 2003 Server before final release and uses a 1142different major/minor version number than Windows XP. 1143 1144Similarly the name "WinWin32s" should have been "Win32s" but has been 1145kept as-is for backwards compatibility reasons too. 1146 1147=item Win32::GetOSVersion() 1148 1149[CORE] Returns the list (STRING, MAJOR, MINOR, BUILD, ID), where the 1150elements are, respectively: An arbitrary descriptive string, the major 1151version number of the operating system, the minor version number, the 1152build number, and a digit indicating the actual operating system. 1153For the ID, the values are 0 for Win32s, 1 for Windows 9X/Me and 2 for 1154Windows NT/2000/XP/2003/Vista/2008/7. In scalar context it returns just 1155the ID. 1156 1157Currently known values for ID MAJOR MINOR and BUILD are as follows: 1158 1159 OS ID MAJOR MINOR BUILD 1160 Win32s 0 - - - 1161 Windows 95 1 4 0 - 1162 Windows 98 1 4 10 - 1163 Windows Me 1 4 90 - 1164 1165 Windows NT 3.51 2 3 51 - 1166 Windows NT 4 2 4 0 - 1167 1168 Windows 2000 2 5 0 - 1169 Windows XP 2 5 1 - 1170 Windows Server 2003 2 5 2 - 1171 Windows Server 2003 R2 2 5 2 - 1172 Windows Home Server 2 5 2 - 1173 1174 Windows Vista 2 6 0 - 1175 Windows Server 2008 2 6 0 - 1176 Windows 7 2 6 1 - 1177 Windows Server 2008 R2 2 6 1 - 1178 Windows 8 2 6 2 - 1179 Windows Server 2012 2 6 2 - 1180 Windows 8.1 2 6 2 - 1181 Windows Server 2012 R2 2 6 2 - 1182 1183 Windows 10 2 10 0 - 1184 Windows Server 2016 2 10 0 14393 1185 Windows Server 2019 2 10 0 17677 1186 1187On Windows NT 4 SP6 and later this function returns the following 1188additional values: SPMAJOR, SPMINOR, SUITEMASK, PRODUCTTYPE. 1189 1190The version numbers for Windows 2003 and Windows Home Server are 1191identical; the SUITEMASK field must be used to differentiate between 1192them. 1193 1194The version numbers for Windows Vista and Windows Server 2008 are 1195identical; the PRODUCTTYPE field must be used to differentiate between 1196them. 1197 1198The version numbers for Windows 7 and Windows Server 2008 R2 are 1199identical; the PRODUCTTYPE field must be used to differentiate between 1200them. 1201 1202The version numbers for Windows 8 and Windows Server 2012 are 1203identical; the PRODUCTTYPE field must be used to differentiate between 1204them. 1205 1206For modern Windows releases, the major and minor version numbers are 1207identical. The PRODUCTTYPE field must be used to differentiate between 1208Windows 10 and Server releases. The BUILD field is used to 1209differentiate Windows Server versions: currently 2016, 2019, and 1210Semi-Annual Channel releases. 1211 1212SPMAJOR and SPMINOR are the version numbers of the latest 1213installed service pack. (In the Windows 10 era, these are unused.) 1214 1215SUITEMASK is a bitfield identifying the product suites available on 1216the system. Known bits are: 1217 1218 VER_SUITE_SMALLBUSINESS 0x00000001 1219 VER_SUITE_ENTERPRISE 0x00000002 1220 VER_SUITE_BACKOFFICE 0x00000004 1221 VER_SUITE_COMMUNICATIONS 0x00000008 1222 VER_SUITE_TERMINAL 0x00000010 1223 VER_SUITE_SMALLBUSINESS_RESTRICTED 0x00000020 1224 VER_SUITE_EMBEDDEDNT 0x00000040 1225 VER_SUITE_DATACENTER 0x00000080 1226 VER_SUITE_SINGLEUSERTS 0x00000100 1227 VER_SUITE_PERSONAL 0x00000200 1228 VER_SUITE_BLADE 0x00000400 1229 VER_SUITE_EMBEDDED_RESTRICTED 0x00000800 1230 VER_SUITE_SECURITY_APPLIANCE 0x00001000 1231 VER_SUITE_STORAGE_SERVER 0x00002000 1232 VER_SUITE_COMPUTE_SERVER 0x00004000 1233 VER_SUITE_WH_SERVER 0x00008000 1234 VER_SUITE_MULTIUSERTS 0x00020000 1235 1236The VER_SUITE_xxx names are listed here to cross reference the Microsoft 1237documentation. The Win32 module does not provide symbolic names for these 1238constants. 1239 1240PRODUCTTYPE provides additional information about the system. It should 1241be one of the following integer values: 1242 1243 1 - Workstation (NT 4, 2000 Pro, XP Home, XP Pro, Vista, etc) 1244 2 - Domaincontroller 1245 3 - Server (2000 Server, Server 2003, Server 2008, etc) 1246 1247Note that a server that is also a domain controller is reported as 1248PRODUCTTYPE 2 (Domaincontroller) and not PRODUCTTYPE 3 (Server). 1249 1250=item Win32::GetShortPathName(PATHNAME) 1251 1252[CORE] Returns a representation of PATHNAME that is composed of short 1253(8.3) path components where available. For path components where the 1254file system has not generated the short form the returned path will 1255use the long form, so this function might still for instance return a 1256path containing spaces. Returns C<undef> when the PATHNAME does not 1257exist. Compare with Win32::GetFullPathName() and 1258Win32::GetLongPathName(). 1259 1260=item Win32::GetSystemMetrics(INDEX) 1261 1262Retrieves the specified system metric or system configuration setting. 1263Please refer to the Microsoft documentation of the GetSystemMetrics() 1264function for a reference of available INDEX values. All system 1265metrics return integer values. 1266 1267=item Win32::GetProcAddress(INSTANCE, PROCNAME) 1268 1269Returns the address of a function inside a loaded library. The 1270information about what you can do with this address has been lost in 1271the mist of time. Use the Win32::API module instead of this deprecated 1272function. 1273 1274=item Win32::GetProcessPrivileges([PID]) 1275 1276Returns a reference to a hash holding the information about the privileges 1277held by the specified process. The keys are privilege names, and the values 1278are booleans indicating whether a given privilege is currently enabled or not. 1279 1280If the optional PID parameter is omitted, the function queries the current 1281process. 1282 1283Example return value: 1284 1285 { 1286 SeTimeZonePrivilege => 0, 1287 SeShutdownPrivilege => 0, 1288 SeUndockPrivilege => 0, 1289 SeIncreaseWorkingSetPrivilege => 0, 1290 SeChangeNotifyPrivilege => 1 1291 } 1292 1293=item Win32::GetProductInfo(OSMAJOR, OSMINOR, SPMAJOR, SPMINOR) 1294 1295Retrieves the product type for the operating system on the local 1296computer, and maps the type to the product types supported by the 1297specified operating system. Please refer to the Microsoft 1298documentation of the GetProductInfo() function for more information 1299about the parameters and return value. This function requires Windows 1300Vista or later. 1301 1302See also the Win32::GetOSName() and Win32::GetOSDisplayName() 1303functions which provide a higher level abstraction of the data 1304returned by this function. 1305 1306=item Win32::GetTickCount() 1307 1308[CORE] Returns the number of milliseconds elapsed since the last 1309system boot. Resolution is limited to system timer ticks (about 10ms 1310on WinNT and 55ms on Win9X). 1311 1312=item Win32::GuidGen() 1313 1314Creates a globally unique 128 bit integer that can be used as a 1315persistent identifier in a distributed setting. To a very high degree 1316of certainty this function returns a unique value. No other 1317invocation, on the same or any other system (networked or not), should 1318return the same value. 1319 1320The return value is formatted according to OLE conventions, as groups 1321of hex digits with surrounding braces. For example: 1322 1323 {09531CF1-D0C7-4860-840C-1C8C8735E2AD} 1324 1325=item Win32::HttpGetFile(URL, FILENAME [, IGNORE_CERT_ERRORS]) 1326 1327Uses the WinHttp library to download the file specified by the URL 1328parameter to the local file specified by FILENAME. The optional third 1329parameter, if true, indicates that certficate errors are to be ignored 1330for https connections; please use with caution in a safe environment, 1331such as when testing locally using a self-signed certificate. 1332 1333Only http and https protocols are supported. Authentication is not 1334supported. The function is not available when building with gcc prior to 13354.8.0 because the WinHttp library is not available. 1336 1337In scalar context returns a boolean success or failure, and in list 1338context also returns, in addition to the boolean status, a second 1339value containing message text related to the status. 1340 1341If the call fails, C<Win32::GetLastError()> will return a numeric 1342error code, which may be a system error, a WinHttp error, or a 1343user-defined error composed of 1e9 plus the HTTP status code. 1344 1345Scalar context example: 1346 1347 print Win32::GetLastError() 1348 unless Win32::HttpGetFile('http://example.com/somefile.tar.gz', 1349 '.\file.tgz'); 1350 1351List context example: 1352 1353 my ($ok, $msg) = Win32::HttpGetFile('http://example.com/somefile.tar.gz', 1354 '.\file.tgz'); 1355 if ($ok) { 1356 print "Success!: $msg\n"; 1357 } 1358 else { 1359 print "Failure!: $msg\n"; 1360 my $err = Win32::GetLastError(); 1361 if ($err > 1e9) { 1362 printf "HTTP status: %d\n", ($err - 1e9); 1363 } 1364 } 1365 1366=item Win32::InitiateSystemShutdown 1367 1368(MACHINE, MESSAGE, TIMEOUT, FORCECLOSE, REBOOT) 1369 1370Shuts down the specified MACHINE, notifying users with the 1371supplied MESSAGE, within the specified TIMEOUT interval. Forces 1372closing of all documents without prompting the user if FORCECLOSE is 1373true, and reboots the machine if REBOOT is true. This function works 1374only on WinNT. 1375 1376=item Win32::IsAdminUser() 1377 1378Returns non zero if the account in whose security context the 1379current process/thread is running belongs to the local group of 1380Administrators in the built-in system domain; returns 0 if not. 1381On Windows Vista it will only return non-zero if the process is 1382actually running with elevated privileges. Returns C<undef> 1383and prints a warning if an error occurred. This function always 1384returns 1 on Win9X. 1385 1386=item Win32::IsDeveloperModeEnabled() 1387 1388Returns true if the developer mode is currently enabled. It always returns 1389false on Windows versions older than Windows 10. 1390 1391=item Win32::IsSymlinkCreationAllowed() 1392 1393Returns true if the current process is allowed to create symbolic links. This 1394function is a convenience wrapper around Win32::GetProcessPrivileges() and 1395Win32::IsDeveloperModeEnabled(). 1396 1397=item Win32::IsWinNT() 1398 1399[CORE] Returns non zero if the Win32 subsystem is Windows NT. 1400 1401=item Win32::IsWin95() 1402 1403[CORE] Returns non zero if the Win32 subsystem is Windows 95. 1404 1405=item Win32::LoadLibrary(LIBNAME) 1406 1407Loads a dynamic link library into memory and returns its module 1408handle. This handle can be used with Win32::GetProcAddress() and 1409Win32::FreeLibrary(). This function is deprecated. Use the Win32::API 1410module instead. 1411 1412=item Win32::LoginName() 1413 1414[CORE] Returns the username of the owner of the current perl process. 1415The return value may be a Unicode string. 1416 1417=item Win32::LookupAccountName(SYSTEM, ACCOUNT, DOMAIN, SID, SIDTYPE) 1418 1419Looks up ACCOUNT on SYSTEM and returns the domain name the SID and 1420the SID type. 1421 1422=item Win32::LookupAccountSID(SYSTEM, SID, ACCOUNT, DOMAIN, SIDTYPE) 1423 1424Looks up SID on SYSTEM and returns the account name, domain name, 1425and the SID type. 1426 1427=item Win32::MsgBox(MESSAGE [, FLAGS [, TITLE]]) 1428 1429Create a dialog box containing MESSAGE. FLAGS specifies the 1430required icon and buttons according to the following table: 1431 1432 0 = OK 1433 1 = OK and Cancel 1434 2 = Abort, Retry, and Ignore 1435 3 = Yes, No and Cancel 1436 4 = Yes and No 1437 5 = Retry and Cancel 1438 1439 MB_ICONSTOP "X" in a red circle 1440 MB_ICONQUESTION question mark in a bubble 1441 MB_ICONEXCLAMATION exclamation mark in a yellow triangle 1442 MB_ICONINFORMATION "i" in a bubble 1443 1444TITLE specifies an optional window title. The default is "Perl". 1445 1446The function returns the menu id of the selected push button: 1447 1448 0 Error 1449 1450 1 OK 1451 2 Cancel 1452 3 Abort 1453 4 Retry 1454 5 Ignore 1455 6 Yes 1456 7 No 1457 1458=item Win32::NodeName() 1459 1460[CORE] Returns the Microsoft Network node-name of the current machine. 1461 1462=item Win32::OutputDebugString(STRING) 1463 1464Sends a string to the application or system debugger for display. 1465The function does nothing if there is no active debugger. 1466 1467Alternatively one can use the I<Debug Viewer> application to 1468watch the OutputDebugString() output: 1469 1470http://www.microsoft.com/technet/sysinternals/utilities/debugview.mspx 1471 1472=item Win32::RegisterServer(LIBRARYNAME) 1473 1474Loads the DLL LIBRARYNAME and calls the function DllRegisterServer. 1475 1476=item Win32::SetChildShowWindow(SHOWWINDOW) 1477 1478[CORE] Sets the I<ShowMode> of child processes started by system(). 1479By default system() will create a new console window for child 1480processes if Perl itself is not running from a console. Calling 1481SetChildShowWindow(0) will make these new console windows invisible. 1482Calling SetChildShowWindow() without arguments reverts system() to the 1483default behavior. The return value of SetChildShowWindow() is the 1484previous setting or C<undef>. 1485 1486The following symbolic constants for SHOWWINDOW are available 1487(but not exported) from the Win32 module: SW_HIDE, SW_SHOWNORMAL, 1488SW_SHOWMINIMIZED, SW_SHOWMAXIMIZED and SW_SHOWNOACTIVATE. 1489 1490=item Win32::SetConsoleCP(ID) 1491 1492Sets the input code page used by the console associated with the 1493calling process. The return value of SetConsoleCP() is nonzero on 1494success or zero on failure. To get the console's input code page, see 1495GetConsoleCP(). 1496 1497=item Win32::SetConsoleOutputCP(ID) 1498 1499Sets the output code page used by the console associated with the 1500calling process. The return value of SetConsoleOutputCP() is nonzero on 1501success or zero on failure. To get the console's output code page, see 1502GetConsoleOutputCP(). 1503 1504=item Win32::SetCwd(NEWDIRECTORY) 1505 1506[CORE] Sets the current active drive and directory. This function does not 1507work with UNC paths, since the functionality required to required for 1508such a feature is not available under Windows 95. 1509 1510=item Win32::SetLastError(ERROR) 1511 1512[CORE] Sets the value of the last error encountered to ERROR. This is 1513that value that will be returned by the Win32::GetLastError() 1514function. 1515 1516=item Win32::Sleep(TIME) 1517 1518[CORE] Pauses for TIME milliseconds. The timeslices are made available 1519to other processes and threads. 1520 1521=item Win32::Spawn(COMMAND, ARGS, PID) 1522 1523[CORE] Spawns a new process using the supplied COMMAND, passing in 1524arguments in the string ARGS. The pid of the new process is stored in 1525PID. This function is deprecated. Please use the Win32::Process module 1526instead. 1527 1528=item Win32::UnregisterServer(LIBRARYNAME) 1529 1530Loads the DLL LIBRARYNAME and calls the function 1531DllUnregisterServer. 1532 1533=back 1534 1535=head1 CAVEATS 1536 1537=head2 Short Path Names 1538 1539There are many situations in which modern Windows systems will not have 1540the L<short path name|https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#short-vs-long-names> 1541(also called 8.3 or MS-DOS) alias for long file names available. 1542 1543Short path support can be configured system-wide via the registry, 1544but the default on modern systems is to configure short path usage per 1545volume. The configuration for a volume can be queried in a number of ways, 1546but these may either be unreliable or require elevated (administrator) 1547privileges. 1548 1549Typically, the configuration for a volume can be queried using the C<fsutil> 1550utility, e.g. C<fsutil 8dot3name query d:>. On the C level, it can be queried 1551with a C<FSCTL_QUERY_PERSISTENT_VOLUME_STATE> request to the 1552C<DeviceIOControl> API call, as described in 1553L<this article|https://www.codeproject.com/Articles/304374/Query-Volume-Setting-for-State-Windows>. 1554However, both of these methods require administrator privileges to work. 1555 1556The Win32 module does not perform any per-volume check and simply fetches 1557short path names in the same manner as the underlying Windows API call it 1558uses: If short path names are disabled, the call will still succeed but the 1559long name will actually be returned. 1560 1561Note that on volumes where this happens, C<GetANSIPathName> usually cannot be 1562used to return useful filenames for files that contain unicode characters. 1563(In code page 65001, this may still work.) Handling unicode filenames in this 1564legacy manner relies upon C<GetShortPathName> returning 8.3 filenames, but 1565without short name support, it will return the filename with all unicode 1566characters replaced by question mark characters. 1567 1568=cut 1569