diff --git a/README.win32 b/README.win32 index 7e6565387e..672601988d 100644 --- a/README.win32 +++ b/README.win32 @@ -485,7 +485,8 @@ You can also control the shell that perl uses to run system() and backtick commands via PERL5SHELL. See L. Perl does not depend on the registry, but it can look up certain default -values if you choose to put them there. On Perl process start Perl checks if +values if you choose to put them there unless disabled at build time with +USE_NO_REGISTRY. On Perl process start Perl checks if C and C exist. If the keys exists, they will be checked for remainder of the Perl process's run life for certain entries. Entries in diff --git a/iperlsys.h b/iperlsys.h index 3aee24f7ce..86ab687fce 100644 --- a/iperlsys.h +++ b/iperlsys.h @@ -478,7 +478,7 @@ typedef char* (*LPENVGetenv_len)(struct IPerlEnv*, #endif #ifdef WIN32 typedef unsigned long (*LPEnvOsID)(struct IPerlEnv*); -typedef char* (*LPEnvLibPath)(struct IPerlEnv*, const char*, +typedef char* (*LPEnvLibPath)(struct IPerlEnv*, WIN32_NO_REGISTRY_M_(const char*) STRLEN *const len); typedef char* (*LPEnvSiteLibPath)(struct IPerlEnv*, const char*, STRLEN *const len); @@ -550,7 +550,7 @@ struct IPerlEnvInfo #define PerlEnv_os_id() \ (*PL_Env->pEnvOsID)(PL_Env) #define PerlEnv_lib_path(str, lenp) \ - (*PL_Env->pLibPath)(PL_Env,(str),(lenp)) + (*PL_Env->pLibPath)(PL_Env,WIN32_NO_REGISTRY_M_(str)(lenp)) #define PerlEnv_sitelib_path(str, lenp) \ (*PL_Env->pSiteLibPath)(PL_Env,(str),(lenp)) #define PerlEnv_vendorlib_path(str, lenp) \ @@ -575,7 +575,7 @@ struct IPerlEnvInfo #ifdef WIN32 #define PerlEnv_os_id() win32_os_id() -#define PerlEnv_lib_path(str, lenp) win32_get_privlib(str, lenp) +#define PerlEnv_lib_path(str, lenp) win32_get_privlib(WIN32_NO_REGISTRY_M_(str) lenp) #define PerlEnv_sitelib_path(str, lenp) win32_get_sitelib(str, lenp) #define PerlEnv_vendorlib_path(str, lenp) win32_get_vendorlib(str, lenp) #define PerlEnv_get_child_IO(ptr) win32_get_child_IO(ptr) diff --git a/perl.c b/perl.c index 7b98b382bc..69cdf8e954 100644 --- a/perl.c +++ b/perl.c @@ -1787,6 +1787,9 @@ S_Internals_V(pTHX_ CV *cv) # ifdef USE_LOCALE_CTYPE " USE_LOCALE_CTYPE" # endif +# ifdef WIN32_NO_REGISTRY + " USE_NO_REGISTRY" +# endif # ifdef USE_PERL_ATOF " USE_PERL_ATOF" # endif diff --git a/pod/perldelta.pod b/pod/perldelta.pod index 414a099d2a..f61cfd35c7 100644 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@ -325,6 +325,14 @@ XXX =item * +A new build option C has been added to the makefiles. This +option is off by default, meaning the default is to do Windows registry lookups. +This option stops Perl from looking inside the registry for anything. For what +values are looked up in the registry see L. Internally, in C, the +name of this option is C. + +=item * + The behavior of Perl using C and C to lookup certain values, including C<%ENV> vars starting with C has changed. Previously, the 2 keys were diff --git a/win32/Makefile b/win32/Makefile index 1a66403425..787d888c2d 100644 --- a/win32/Makefile +++ b/win32/Makefile @@ -95,6 +95,13 @@ USE_LARGE_FILES = define # #USE_64_BIT_INT = define +# +# Uncomment this if you want to disable looking up values from +# HKEY_CURRENT_USER\Software\Perl and HKEY_LOCAL_MACHINE\Software\Perl in +# the Registry. +# +#USE_NO_REGISTRY = define + # # uncomment exactly one of the following # @@ -294,6 +301,10 @@ USE_LARGE_FILES = undef USE_64_BIT_INT = undef !ENDIF +!IF "$(USE_NO_REGISTRY)" == "" +USE_NO_REGISTRY = undef +!ENDIF + !IF "$(USE_IMP_SYS)$(USE_MULTI)" == "defineundef" USE_MULTI = define !ENDIF @@ -314,6 +325,10 @@ BUILDOPT = $(BUILDOPT) -DPERL_IMPLICIT_CONTEXT BUILDOPT = $(BUILDOPT) -DPERL_IMPLICIT_SYS !ENDIF +!IF "$(USE_NO_REGISTRY)" != "undef" +BUILDOPT = $(BUILDOPT) -DWIN32_NO_REGISTRY +!ENDIF + !IF "$(PROCESSOR_ARCHITECTURE)" == "" PROCESSOR_ARCHITECTURE = x86 !ENDIF @@ -388,7 +403,16 @@ ARCHNAME = $(ARCHNAME)-64int # All but the free version of VC++ 7.1 can load DLLs on demand. Makes the test # suite run in about 10% less time. !IF "$(CCTYPE)" != "MSVC70FREE" +# If no registry, advapi32 is only used for Perl_pp_getlogin/getlogin/GetUserNameA +# which is rare to execute +!IF "$(USE_NO_REGISTRY)" != "undef" +DELAYLOAD = -DELAYLOAD:ws2_32.dll -DELAYLOAD:advapi32.dll delayimp.lib +MINIDELAYLOAD = +!ELSE DELAYLOAD = -DELAYLOAD:ws2_32.dll delayimp.lib +#miniperl never does any registry lookups +MINIDELAYLOAD = -DELAYLOAD:advapi32.dll +!ENDIF !ENDIF # Visual C++ 2005 and 2008 (VC++ 8.0 and 9.0) create manifest files for EXEs and @@ -1023,7 +1047,7 @@ $(MINIPERL) : ..\lib\buildcustomize.pl ..\lib\buildcustomize.pl : $(MINIDIR) $(MINI_OBJ) ..\write_buildcustomize.pl $(LINK32) -out:$(MINIPERL) @<< - $(BLINK_FLAGS) $(DELAYLOAD) $(LIBFILES) $(MINI_OBJ) + $(BLINK_FLAGS) $(DELAYLOAD) $(MINIDELAYLOAD) $(LIBFILES) $(MINI_OBJ) << $(EMBED_EXE_MANI:..\lib\buildcustomize.pl=..\miniperl.exe) $(MINIPERL) -I..\lib -f ..\write_buildcustomize.pl .. diff --git a/win32/makefile.mk b/win32/makefile.mk index 543cb93574..83850c3580 100644 --- a/win32/makefile.mk +++ b/win32/makefile.mk @@ -107,6 +107,13 @@ USE_LARGE_FILES *= define # #USE_LONG_DOUBLE *=define +# +# Uncomment this if you want to disable looking up values from +# HKEY_CURRENT_USER\Software\Perl and HKEY_LOCAL_MACHINE\Software\Perl in +# the Registry. +# +#USE_NO_REGISTRY *=define + # # uncomment exactly one of the following # @@ -310,6 +317,7 @@ USE_IMP_SYS *= undef USE_LARGE_FILES *= undef USE_64_BIT_INT *= undef USE_LONG_DOUBLE *= undef +USE_NO_REGISTRY *= undef .IF "$(USE_IMP_SYS)" == "define" PERL_MALLOC = undef @@ -343,6 +351,10 @@ BUILDOPT += -DPERL_IMPLICIT_CONTEXT BUILDOPT += -DPERL_IMPLICIT_SYS .ENDIF +.IF "$(USE_NO_REGISTRY)" != "undef" +BUILDOPT += -DWIN32_NO_REGISTRY +.ENDIF + PROCESSOR_ARCHITECTURE *= x86 .IF "$(WIN64)" == "undef" @@ -524,7 +536,16 @@ TESTPREPGCC = test-prep-gcc # All but the free version of VC++ 7.1 can load DLLs on demand. Makes the test # suite run in about 10% less time. .IF "$(CCTYPE)" != "MSVC70FREE" +# If no registry, advapi32 is only used for Perl_pp_getlogin/getlogin/GetUserNameA +# which is rare to execute +.IF "$(USE_NO_REGISTRY)" != "undef" +DELAYLOAD = -DELAYLOAD:ws2_32.dll -DELAYLOAD:advapi32.dll delayimp.lib +MINIDELAYLOAD = +.ELSE DELAYLOAD = -DELAYLOAD:ws2_32.dll delayimp.lib +#miniperl never does any registry lookups +MINIDELAYLOAD = -DELAYLOAD:advapi32.dll +.ENDIF .ENDIF # Visual C++ 2005 and 2008 (VC++ 8.0 and 9.0) create manifest files for EXEs and @@ -1116,7 +1137,7 @@ $(CONFIGPM): ..\config.sh config_h.PL $(mktmp $(LKPRE) $(MINI_OBJ) $(LIBFILES) $(LKPOST)) .ELSE $(LINK32) -out:$(MINIPERL) $(BLINK_FLAGS) \ - @$(mktmp $(DELAYLOAD) $(LIBFILES) $(MINI_OBJ)) + @$(mktmp $(DELAYLOAD) $(MINIDELAYLOAD) $(LIBFILES) $(MINI_OBJ)) $(EMBED_EXE_MANI:s/$@/$(MINIPERL)/) .ENDIF $(MINIPERL) -I..\lib -f ..\write_buildcustomize.pl .. diff --git a/win32/perlhost.h b/win32/perlhost.h index 7a0c3b39d1..ce31f6995e 100644 --- a/win32/perlhost.h +++ b/win32/perlhost.h @@ -514,9 +514,9 @@ PerlEnvOsId(struct IPerlEnv* piPerl) } char* -PerlEnvLibPath(struct IPerlEnv* piPerl, const char *pl, STRLEN *const len) +PerlEnvLibPath(struct IPerlEnv* piPerl, WIN32_NO_REGISTRY_M_(const char *pl) STRLEN *const len) { - return win32_get_privlib(pl, len); + return win32_get_privlib(WIN32_NO_REGISTRY_M_(pl) len); } char* diff --git a/win32/win32.c b/win32/win32.c index 466922f81e..a3e1754893 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -114,12 +114,17 @@ static void my_invalid_parameter_handler(const wchar_t* expression, unsigned int line, uintptr_t pReserved); #endif +#ifndef WIN32_NO_REGISTRY static char* get_regstr_from(HKEY hkey, const char *valuename, SV **svp); static char* get_regstr(const char *valuename, SV **svp); +#endif + static char* get_emd_part(SV **prev_pathp, STRLEN *const len, char *trailing, ...); -static char* win32_get_xlib(const char *pl, const char *xlib, +static char* win32_get_xlib(const char *pl, + WIN32_NO_REGISTRY_M_(const char *xlib) const char *libname, STRLEN *const len); + static BOOL has_shell_metachars(const char *ptr); static long tokenize(const char *str, char **dest, char ***destv); static void get_shell(void); @@ -167,9 +172,11 @@ END_EXTERN_C static OSVERSIONINFO g_osver = {0, 0, 0, 0, 0, ""}; +#ifndef WIN32_NO_REGISTRY /* initialized by Perl_win32_init/PERL_SYS_INIT */ static HKEY HKCU_Perl_hnd; static HKEY HKLM_Perl_hnd; +#endif #ifdef SET_INVALID_PARAMETER_HANDLER static BOOL silent_invalid_parameter_handler = FALSE; @@ -258,6 +265,7 @@ set_w32_module_name(void) } } +#ifndef WIN32_NO_REGISTRY /* *svp (if non-NULL) is expected to be POK (valid allocated SvPVX(*svp)) */ static char* get_regstr_from(HKEY handle, const char *valuename, SV **svp) @@ -305,6 +313,7 @@ get_regstr(const char *valuename, SV **svp) } return str; } +#endif /* ifndef WIN32_NO_REGISTRY */ /* *prev_pathp (if non-NULL) is expected to be POK (valid allocated SvPVX(sv)) */ static char * @@ -374,41 +383,49 @@ get_emd_part(SV **prev_pathp, STRLEN *const len, char *trailing_path, ...) } EXTERN_C char * -win32_get_privlib(const char *pl, STRLEN *const len) +win32_get_privlib(WIN32_NO_REGISTRY_M_(const char *pl) STRLEN *const len) { char *stdlib = "lib"; - char buffer[MAX_PATH+1]; SV *sv = NULL; +#ifndef WIN32_NO_REGISTRY + char buffer[MAX_PATH+1]; /* $stdlib = $HKCU{"lib-$]"} || $HKLM{"lib-$]"} || $HKCU{"lib"} || $HKLM{"lib"} || ""; */ sprintf(buffer, "%s-%s", stdlib, pl); if (!get_regstr(buffer, &sv)) (void)get_regstr(stdlib, &sv); +#endif /* $stdlib .= ";$EMD/../../lib" */ return get_emd_part(&sv, len, stdlib, ARCHNAME, "bin", NULL); } static char * -win32_get_xlib(const char *pl, const char *xlib, const char *libname, - STRLEN *const len) +win32_get_xlib(const char *pl, WIN32_NO_REGISTRY_M_(const char *xlib) + const char *libname, STRLEN *const len) { +#ifndef WIN32_NO_REGISTRY char regstr[40]; +#endif char pathstr[MAX_PATH+1]; SV *sv1 = NULL; SV *sv2 = NULL; +#ifndef WIN32_NO_REGISTRY /* $HKCU{"$xlib-$]"} || $HKLM{"$xlib-$]"} . ---; */ sprintf(regstr, "%s-%s", xlib, pl); (void)get_regstr(regstr, &sv1); +#endif /* $xlib .= * ";$EMD/" . ((-d $EMD/../../../$]) ? "../../.." : "../.."). "/$libname/$]/lib"; */ sprintf(pathstr, "%s/%s/lib", libname, pl); (void)get_emd_part(&sv1, NULL, pathstr, ARCHNAME, "bin", pl, NULL); +#ifndef WIN32_NO_REGISTRY /* $HKCU{$xlib} || $HKLM{$xlib} . ---; */ (void)get_regstr(xlib, &sv2); +#endif /* $xlib .= * ";$EMD/" . ((-d $EMD/../../../$]) ? "../../.." : "../.."). "/$libname/lib"; */ @@ -433,7 +450,7 @@ win32_get_xlib(const char *pl, const char *xlib, const char *libname, EXTERN_C char * win32_get_sitelib(const char *pl, STRLEN *const len) { - return win32_get_xlib(pl, "sitelib", "site", len); + return win32_get_xlib(pl, WIN32_NO_REGISTRY_M_("sitelib") "site", len); } #ifndef PERL_VENDORLIB_NAME @@ -443,7 +460,7 @@ win32_get_sitelib(const char *pl, STRLEN *const len) EXTERN_C char * win32_get_vendorlib(const char *pl, STRLEN *const len) { - return win32_get_xlib(pl, "vendorlib", PERL_VENDORLIB_NAME, len); + return win32_get_xlib(pl, WIN32_NO_REGISTRY_M_("vendorlib") PERL_VENDORLIB_NAME, len); } static BOOL @@ -1824,12 +1841,14 @@ win32_getenv(const char *name) } FreeEnvironmentStrings(envv); } +#ifndef WIN32_NO_REGISTRY else { /* last ditch: allow any environment variables that begin with 'PERL' to be obtained from the registry, if found there */ if (strncmp(name, "PERL", 4) == 0) (void)get_regstr(name, &curitem); } +#endif } if (curitem && SvCUR(curitem)) return SvPVX(curitem); @@ -4451,6 +4470,8 @@ Perl_win32_init(int *argcp, char ***argvp) #endif ansify_path(); + +#ifndef WIN32_NO_REGISTRY { LONG retval; retval = RegOpenKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Perl", 0, KEY_READ, &HKCU_Perl_hnd); @@ -4462,6 +4483,7 @@ Perl_win32_init(int *argcp, char ***argvp) HKLM_Perl_hnd = NULL; } } +#endif } void @@ -4471,11 +4493,13 @@ Perl_win32_term(void) OP_REFCNT_TERM; PERLIO_TERM; MALLOC_TERM; +#ifndef WIN32_NO_REGISTRY /* handles might be NULL, RegCloseKey then returns ERROR_INVALID_HANDLE but no point of checking and we can't die() at this point */ RegCloseKey(HKLM_Perl_hnd); RegCloseKey(HKCU_Perl_hnd); /* the handles are in an undefined state until the next PERL_SYS_INIT3 */ +#endif } void diff --git a/win32/win32.h b/win32/win32.h index 3b35b6c2a4..e997651c15 100644 --- a/win32/win32.h +++ b/win32/win32.h @@ -24,6 +24,9 @@ /* less I/O calls during each require */ # define PERL_DISABLE_PMC +/* unnecessery for miniperl to lookup anything from an "installed" perl */ +# define WIN32_NO_REGISTRY + /* allow minitest to work */ # define PERL_TEXTMODE_SCRIPTS #endif @@ -206,6 +209,13 @@ struct utsname { # define PERL_SOCK_SYSWRITE_IS_SEND #endif +#ifdef WIN32_NO_REGISTRY +/* the last _ in WIN32_NO_REGISTRY_M_ is like the _ in aTHX_ */ +# define WIN32_NO_REGISTRY_M_(x) +#else +# define WIN32_NO_REGISTRY_M_(x) x, +#endif + #define PERL_NO_FORCE_LINK /* no need for PL_force_link_funcs */ #define ENV_IS_CASELESS @@ -394,7 +404,7 @@ DllExport HWND win32_create_message_window(void); DllExport int win32_async_check(pTHX); extern int my_fclose(FILE *); -extern char * win32_get_privlib(const char *pl, STRLEN *const len); +extern char * win32_get_privlib(WIN32_NO_REGISTRY_M_(const char *pl) STRLEN *const len); extern char * win32_get_sitelib(const char *pl, STRLEN *const len); extern char * win32_get_vendorlib(const char *pl, STRLEN *const len); diff --git a/win32/wince.c b/win32/wince.c index 1b58d40ef7..bcc66c8c12 100644 --- a/win32/wince.c +++ b/win32/wince.c @@ -230,7 +230,7 @@ get_emd_part(SV **prev_pathp, STRLEN *const len, char *trailing_path, ...) } char * -win32_get_privlib(const char *pl, STRLEN *const len) +win32_get_privlib(WIN32_NO_REGISTRY_M_(const char *pl) STRLEN *const len) { dTHX; char *stdlib = "lib";