develooper Front page | perl.perl5.porters | Postings from May 2015

[perl #123658] [PATCH] stop checking the Win32 registry if *"/Software/Perl" doesn't exist

Thread Previous
From:
bulk88 via RT
Date:
May 28, 2015 19:49
Subject:
[perl #123658] [PATCH] stop checking the Win32 registry if *"/Software/Perl" doesn't exist
Message ID:
rt-4.0.18-11582-1432842560-452.123658-15-0@perl.org
I also have a dream, so that with-registry-on builds, do not use advapi32 for anything except GetUserNameA, the registry lookups instead use Native API, from ntdll.dll. ntdll.dll is in every process, advapi32 is optional. Advapi32's registry API allows you to read/write/modify the registry of another windows computer over a LAN, as easily as your own local registry. But nobody except for MSCE IT depts will ever use remote registry service and DCOM, and Perl has no business using a foreign machine's registry for its ENV var overrides. So the registry lookups go through ntdll.dll, the GetUserNameA stays as part of advapi32 and runs through a delay load of advapi32. (GetUserNameA is a RPC call to LSASS service using NT LPC ports in every implementation, there is no Native [user mode] (ntdll/ntoskrnl) API, the kernel driver API equivalent for GetUserNameA in ksecdd.sys also does LPC port RPC to LSASS, so there is no advantage in not using the public api and ksecdd.sys is not acce
 ssible from user mode (not in the SSDT)). GetUserNameA is a simple stub in advapi32 for secur32.dll's GetUserNameExA function. advapi32 itself delay loads secur32.dll if you call advapi32's GetUserNameA.

The shim is

BOOL __stdcall GetUserNameA(LPSTR lpBuffer, LPDWORD pcbBuffer)
{
  return GetUserNameExA((EXTENDED_NAME_FORMAT)65538, lpBuffer, pcbBuffer);
}

Looking at my winxp secur32.dll, I see secur32.dll loads advapi32.dll, so whether you delay load with Perl on GetUserNameA/advapi32.dll or GetUserNameExA/secur32.dll, when you call either both advapi32 and secur32 will wind up being loaded into the perl process in any case, the point is to keep advapi32/secur32.dll/rpcrt4.dll out of the process until you call getlogin. I need to do some research if calling GetUserNameExA/secur32.dll will trigger advapi32 to instantly delay load/bind itself to secur32 or not (perl->DelayLoadDLL@perl522.dll->GetUserNameExA@secur32.dll->FooBar@advapi32.dll->DelayLoadDLL@advapi32.dll->Baz@secur32.dll). If advapi32.dll stays unbound and unaware that secur32.dll is in the process even though secur32.dll is what loaded advapi32.dll into the process, some CPU and maybe a COW mem page (4KB) representing the delay import table in advapi32.dll is saved. Static dynamic linking is more efficient than the VC delay loader code I believe. For example the VC 
 delay loader uses GetProcAddress, and each call to GetProcAddress has to get the DLL Loader mutex, while using static dynamic linking the lock is obtained once inside LoadLibrary() in kernel32/Ldr*() in ntdll.

-- 
bulk88 ~ bulk88 at hotmail.com

---
via perlbug:  queue: perl5 status: open
https://rt.perl.org/Ticket/Display.html?id=123658

Thread Previous


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About