Skip to content

Commit 6f646c9

Browse files
committed
implement IsDeveloperModeEnabled()
It's the second step towards IsSymlinkCreationAllowed().
1 parent f79a084 commit 6f646c9

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

Win32.pm

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,6 +1304,11 @@ actually running with elevated privileges. Returns C<undef>
13041304
and prints a warning if an error occurred. This function always
13051305
returns 1 on Win9X.
13061306
1307+
=item Win32::IsDeveloperModeEnabled()
1308+
1309+
Returns true if the developer mode is currently enabled. It always returns
1310+
false on Windows versions older than Windows 10.
1311+
13071312
=item Win32::IsWinNT()
13081313
13091314
[CORE] Returns non zero if the Win32 subsystem is Windows NT.

Win32.xs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ typedef int (__stdcall *PFNDllUnregisterServer)(void);
3030
typedef BOOL (__stdcall *PFNIsUserAnAdmin)(void);
3131
typedef BOOL (WINAPI *PFNGetProductInfo)(DWORD, DWORD, DWORD, DWORD, DWORD*);
3232
typedef void (WINAPI *PFNGetNativeSystemInfo)(LPSYSTEM_INFO lpSystemInfo);
33+
typedef LONG (*PFNRegGetValueA)(HKEY, LPCSTR, LPCSTR, DWORD, LPDWORD, PVOID, LPDWORD);
3334

3435
#ifndef CSIDL_MYMUSIC
3536
# define CSIDL_MYMUSIC 0x000D
@@ -1643,6 +1644,44 @@ XS(w32_GetProcessPrivileges)
16431644
XSRETURN(1);
16441645
}
16451646

1647+
XS(w32_IsDeveloperModeEnabled)
1648+
{
1649+
dXSARGS;
1650+
LONG status;
1651+
DWORD val, val_size = sizeof(val);
1652+
PFNRegGetValueA pfnRegGetValueA;
1653+
HMODULE module;
1654+
1655+
if (items)
1656+
Perl_croak(aTHX_ "usage: Win32::IsDeveloperModeEnabled()");
1657+
1658+
EXTEND(SP, 1);
1659+
1660+
/* developer mode was introduced in Windows 10 */
1661+
if (g_osver.dwMajorVersion < 10)
1662+
XSRETURN_NO;
1663+
1664+
module = GetModuleHandleA("advapi32.dll");
1665+
GETPROC(RegGetValueA);
1666+
if (!pfnRegGetValueA)
1667+
XSRETURN_NO;
1668+
1669+
status = pfnRegGetValueA(
1670+
HKEY_LOCAL_MACHINE,
1671+
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock",
1672+
"AllowDevelopmentWithoutDevLicense",
1673+
RRF_RT_REG_DWORD | KEY_WOW64_64KEY,
1674+
NULL,
1675+
&val,
1676+
&val_size
1677+
);
1678+
1679+
if (status == ERROR_SUCCESS && val == 1)
1680+
XSRETURN_YES;
1681+
1682+
XSRETURN_NO;
1683+
}
1684+
16461685
MODULE = Win32 PACKAGE = Win32
16471686

16481687
PROTOTYPES: DISABLE
@@ -1713,6 +1752,7 @@ BOOT:
17131752
newXS("Win32::SetConsoleCP", w32_SetConsoleCP, file);
17141753
newXS("Win32::SetConsoleOutputCP", w32_SetConsoleOutputCP, file);
17151754
newXS("Win32::GetProcessPrivileges", w32_GetProcessPrivileges, file);
1755+
newXS("Win32::IsDeveloperModeEnabled", w32_IsDeveloperModeEnabled, file);
17161756
#ifdef __CYGWIN__
17171757
newXS("Win32::SetChildShowWindow", w32_SetChildShowWindow, file);
17181758
#endif

t/Privileges.t

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use warnings;
44
use Test;
55
use Win32;
66

7-
plan tests => 4;
7+
plan tests => 5;
88

99
ok(ref(Win32::GetProcessPrivileges) eq 'HASH');
1010
ok(ref(Win32::GetProcessPrivileges(Win32::GetCurrentProcessId())) eq 'HASH');
@@ -25,3 +25,8 @@ skip($skip, sub{
2525

2626
return 1;
2727
});
28+
29+
# there isn't really anything to test, we just want to make sure that the
30+
# function doesn't segfault
31+
Win32::IsDeveloperModeEnabled();
32+
ok(1);

0 commit comments

Comments
 (0)