You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by William A Rowe Jr <wr...@rowe-clan.net> on 2019/12/13 01:59:28 UTC

Re: svn commit: r1871082 - in /apr/apr/trunk: include/arch/win32/apr_arch_misc.h misc/win32/misc.c misc/win32/start.c

Awesome :)

Thanks!

On Mon, Dec 9, 2019, 04:22 <iv...@apache.org> wrote:

> Author: ivan
> Date: Mon Dec  9 10:22:08 2019
> New Revision: 1871082
>
> URL: http://svn.apache.org/viewvc?rev=1871082&view=rev
> Log:
> win32: Try to avoid loading shell32.dll whenever possible:
> 1. shell32.dll has about 19 dependencies.
> 2. shell32.dll depends on user32/gdi32.dll and loading them makes the
> process
>    a "GUI" process:
>    - this slows down process initialization and shutdown [1]
>    - doesn't allow enabling mitigation to block win32k.sys
>      for process using APR.
> 3. shell32.dll is not available on Windows Nano Server
>
> The only used function from shell32.dll is CommandLineToArgW. It is used to
> parse command-line arguments in apr_app_initialize().
>
> The solution is twofold:
> 1. Delay loading shell32.dll.
> 2. Prefer to use api-ms-win-downlevel-shell32-l1-1-0.dll API Set instead of
>    shell32.dll (Windows 8+)
>
> * include/arch/win32/apr_arch_misc.h
>   (apr_dlltoken_e): Add DLL_API_MS_WIN_DOWNLEVEL_SHELL32_L1_1_0.
>   (CommandLineToArgvW): Add late late dll func for CommandLineToArgvW.
>
> * misc/win32/misc.c
>   (load_dll_callback): Support API Sets.
>
> * misc/win32/start.c
>   (apr_app_initialize): Use apr_winapi_CommandLineToArgvW() instead of
>    CommandLineToArgvW().
>
> [1]
> https://randomascii.wordpress.com/2018/12/03/a-not-called-function-can-cause-a-5x-slowdown/
>
> Modified:
>     apr/apr/trunk/include/arch/win32/apr_arch_misc.h
>     apr/apr/trunk/misc/win32/misc.c
>     apr/apr/trunk/misc/win32/start.c
>
> Modified: apr/apr/trunk/include/arch/win32/apr_arch_misc.h
> URL:
> http://svn.apache.org/viewvc/apr/apr/trunk/include/arch/win32/apr_arch_misc.h?rev=1871082&r1=1871081&r2=1871082&view=diff
>
> ==============================================================================
> --- apr/apr/trunk/include/arch/win32/apr_arch_misc.h (original)
> +++ apr/apr/trunk/include/arch/win32/apr_arch_misc.h Mon Dec  9 10:22:08
> 2019
> @@ -188,7 +188,10 @@ typedef enum {
>      DLL_SHSTDAPI = 4,      /* shell32  From ShellAPI.h      */
>      DLL_NTDLL = 5,         /* ntdll    From our real kernel */
>      DLL_IPHLPAPI = 6,      /* Iphlpapi From Iphlpapi.h      */
> -    DLL_defined = 7        /* must define as last idx_ + 1  */
> +    DLL_API_MS_WIN_DOWNLEVEL_SHELL32_L1_1_0 = 7,
> +                           /* api-ms-win-downlevel-shell32-l1-1-0.dll,
> +                              fallback to shell32.dll       */
> +    DLL_defined = 8        /* must define as last idx_ + 1  */
>  } apr_dlltoken_e;
>
>  FARPROC apr_load_dll_func(apr_dlltoken_e fnLib, char *fnName, int
> ordinal);
> @@ -312,6 +315,11 @@ APR_DECLARE_LATE_DLL_FUNC(DLL_IPHLPAPI,
>      (InterfaceIndex, InterfaceName));
>  #define if_indextoname apr_winapi_if_indextoname
>
> +APR_DECLARE_LATE_DLL_FUNC(DLL_SHSTDAPI, LPWSTR *, STDAPICALLTYPE,
> CommandLineToArgvW, 0, (
> +    LPCWSTR lpCmdLine,
> +    int *pNumArgs),
> +    (lpCmdLine, pNumArgs));
> +
>  #endif /* !defined(_WIN32_WCE) */
>
>  #endif  /* ! MISC_H */
>
> Modified: apr/apr/trunk/misc/win32/misc.c
> URL:
> http://svn.apache.org/viewvc/apr/apr/trunk/misc/win32/misc.c?rev=1871082&r1=1871081&r2=1871082&view=diff
>
> ==============================================================================
> --- apr/apr/trunk/misc/win32/misc.c (original)
> +++ apr/apr/trunk/misc/win32/misc.c Mon Dec  9 10:22:08 2019
> @@ -136,18 +136,21 @@ apr_status_t apr_get_oslevel(apr_oslevel
>
>  typedef struct win32_late_dll_t {
>      INIT_ONCE control;
> +    const apr_wchar_t *apiset_name;
>      const apr_wchar_t *dll_name;
>      HMODULE dll_handle;
>  } win32_late_dll_t;
>
>  static win32_late_dll_t late_dll[DLL_defined] = {
> -    {INIT_ONCE_STATIC_INIT, L"kernel32", NULL},
> -    {INIT_ONCE_STATIC_INIT, L"advapi32", NULL},
> -    {INIT_ONCE_STATIC_INIT, L"mswsock", NULL},
> -    {INIT_ONCE_STATIC_INIT, L"ws2_32", NULL},
> -    {INIT_ONCE_STATIC_INIT, L"shell32", NULL},
> -    {INIT_ONCE_STATIC_INIT, L"ntdll.dll", NULL},
> -    {INIT_ONCE_STATIC_INIT, L"Iphplapi", NULL}
> +    {INIT_ONCE_STATIC_INIT, NULL, L"kernel32", NULL},
> +    {INIT_ONCE_STATIC_INIT, NULL, L"advapi32", NULL},
> +    {INIT_ONCE_STATIC_INIT, NULL, L"mswsock", NULL},
> +    {INIT_ONCE_STATIC_INIT, NULL, L"ws2_32", NULL},
> +    {INIT_ONCE_STATIC_INIT, NULL, L"shell32", NULL},
> +    {INIT_ONCE_STATIC_INIT, NULL, L"ntdll.dll", NULL},
> +    {INIT_ONCE_STATIC_INIT, NULL, L"Iphplapi", NULL},
> +    {INIT_ONCE_STATIC_INIT, L"api-ms-win-downlevel-shell32-l1-1-0.dll",
> +     L"shell32", NULL}
>  };
>
>  static BOOL WINAPI load_dll_callback(PINIT_ONCE InitOnce,
> @@ -156,7 +159,15 @@ static BOOL WINAPI load_dll_callback(PIN
>  {
>      win32_late_dll_t *dll = Parameter;
>
> -    dll->dll_handle = LoadLibraryW(dll->dll_name);
> +    /* Try api set dll first if defined. */
> +    if (dll->apiset_name) {
> +        dll->dll_handle = LoadLibraryExW(dll->apiset_name, NULL,
> +                                         LOAD_LIBRARY_SEARCH_SYSTEM32);
> +    }
> +
> +    if (!dll->dll_handle) {
> +        dll->dll_handle = LoadLibraryW(dll->dll_name);
> +    }
>
>      return TRUE;
>  }
>
> Modified: apr/apr/trunk/misc/win32/start.c
> URL:
> http://svn.apache.org/viewvc/apr/apr/trunk/misc/win32/start.c?rev=1871082&r1=1871081&r2=1871082&view=diff
>
> ==============================================================================
> --- apr/apr/trunk/misc/win32/start.c (original)
> +++ apr/apr/trunk/misc/win32/start.c Mon Dec  9 10:22:08 2019
> @@ -124,7 +124,7 @@ APR_DECLARE(apr_status_t) apr_app_initia
>
>          sysstr = GetCommandLineW();
>          if (sysstr) {
> -            wstrs = CommandLineToArgvW(sysstr, &wstrc);
> +            wstrs = apr_winapi_CommandLineToArgvW(sysstr, &wstrc);
>              if (wstrs) {
>                  *argc = apr_wastrtoastr(argv, wstrs, wstrc);
>                  LocalFree(wstrs);
>
>
>