This should eliminate any confusion due to a Standard user needing to elevate
to Admin privileges, since from that point on Windows tells the running
program the current user is that Admin. Bypass all that.
run the viewer from the installer.
Turns out that the peculiar indirection through explorer.exe was a known trick
for an elevated-privileges program to launch a program as the logged-in
Windows user. (They could have commented that...)
But explorer.exe doesn't pass command-line parameters, so if you want to pass
any such to the actual target program, you have to launch a shortcut with
those parameters.
But this target program (the updater) and its parameters (precheck mumble) are
specific to the very first viewer run after installation, so delete it after.
Having an additional permanent icon that always runs the updater before the
viewer would only confuse matters.
viewer_manifest.py was signing updater.exe within the package, and then
signing the installer executable itself, but not the actual viewer executable.
Add that.
We used to have to use #if LL_WINDOWS logic to pass std::mem_fun1() to
llbind2nd() instead of std::mem_fun() elsewhere. VS 2017 no longer supports
std::mem_fun1(), which means we can eliminate the special case for Windows.
The Microsoft _open_osfhandle() opens a HANDLE to produce a C-style int file
descriptor suitable for passing to _fdopen(). We used to cast the HANDLEs
returned by GetStdHandle() to long to pass to _open_osfhandle(). Since HANDLE
is an alias for a pointer, this no longer works.
Fortunately _open_osfhandle() now accepts intptr_t, so we can change the
relevant GetStdHandle() calls. (But why not simply accept HANDLE in the first
place?)
VS 2017 complains about the same thing that clang does: casting S32 to GLvoid*
can't possibly produce a valid pointer value because S32 can't fit a whole
64-bit pointer. To appease it, not only must we use reinterpret_cast, but we
must first cast S32 to intptr_t and then reinterpret_cast THAT.
llcorehttp's test_allocator.{h,cpp} overrides global operator new(), operator
new[](), operator delete() and operator delete[](). The two operator new()
functions used to be declared with throw(std::bad_alloc). Worse, for VS 2013
and previous, we needed _THROW0() and _THROW1(std::bad_alloc) instead,
requiring #if logic.
But with dynamic throw declarations deprecated, we must actually remove those.
That obviates the THROW_BAD_ALLOC() / THROW_NOTHING() workarounds in
test_allocator.cpp.
In three different places we use the same pattern: an ssl_thread_id_callback()
function (a static member of LLCrashLogger, in that case) that used to be
passed to CRYPTO_set_id_callback() and therefore returned an unsigned long
representing the ID of the current thread.
But GetCurrentThread() is a HANDLE, an alias for a pointer, and you can't
uniquely cram a 64-bit pointer into an unsigned long.
Fortunately OpenSSL has a more modern API for retrieving thread ID. Pass
each ssl_thread_id_callback() function to CRYPTO_THREADID_set_callback()
instead, converting it to accept CRYPTO_THREADID* and call
CRYPTO_THREADID_set_pointer() or CRYPTO_THREADID_set_numeric() as appropriate().
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/snprintf-snprintf-snprintf-l-snwprintf-snwprintf-l?view=vs-2017
"Beginning with the UCRT in Visual Studio 2015 and Windows 10, snprintf is no
longer identical to _snprintf. The snprintf function behavior is now C99
standard compliant."
In other words, VS 2015 et ff. snprintf() now promises to nul-terminate the
buffer even in the overflow case, which is what snprintf_hack::snprintf() was
for.
This removal was motivated by ambiguous-call errors generated by VS 2017 for
library snprintf() vs. snprintf_hack::snprintf().
process_directory() and process_file() are reached both from the top-level
caller (try_path(), a local function within LLManifest.path()) and recursively
from process_directory(). Both places tested os.path.isdir(source), and if so
called process_directory(), else process_file(). Both places were wrong, as it
turns out.
os.path.isdir(symlink_to_directory) returns True. That meant that despite
explicit logic in ccopymumble() to recreate symlinks in the destination area,
we were consistently recopying the contents of symlinked directories.
The downside to this -- in addition to inflating the size of the installer! --
is that macOS is very particular about the structure of a Framework bundle. It
*must* include a Versions/Current symlink identifying which of the other
Versions subdirectories is, in fact, current. If Current is itself a
subdirectory, codesign can't figure out how to sign the framework, and fails.
The logic for deciding between process_directory() and process_file() must
explicitly check for os.path.islink(source). Rather than replicating that
change in both places, introduce process_either() which decides how to forward
the call, and call it both from try_path() and from process_directory().