Don't try to load kernel32.dll in RWLockWin class

The RWLockWin::Create() function returns NULL on some Windows platforms because it cannot load kernel32.dll. This causes a crash.
RWLockWin tries to load kernel32.dll to check if the Slim Reader/Writer Lock APIs are present in kernel32.dll but on newer Windows platforms, kernel32.dll does not exist and the APIs are exported by kernelbase.dll instead.

The fix is quite simple: There is no need to try to load any DLL to check if the Slim Reader/Writer Lock APIs are present, because these APIs
are always present in all Windows versions since Windows Vista.
I am removing the code that attempts to load kernel32.dll. This prevents the crash on platforms that use kernelbase.dll.

If the WINUWP preprocessor symbol is defined, RWLockWin was already doing the right thing. But this issue is not limited to WINUWP and in
some scenarios, building for WINUWP is not the right solution because it causes other problems. So, my fix is essentially to use the WINUWP
code path for all Windows builds.

The only version of Windows which does not have the Slim Reader/Writer Lock APIs is Windows XP (and older ones, of course.)
However, since the current code does not fall back to an alternative implementation when the Slim Reader/Writer Lock APIs are missing,
WebRTC is already broken on such old versions of Windows.

Bug: webrtc:11186
Change-Id: I34aad066e18b924792d47c244ecee00669e86c4d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/161472
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Henrik Andreassson <henrika@webrtc.org>
Reviewed-by: Tommi <tommi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30044}
This commit is contained in:
Anders Klemets 2019-12-09 09:34:49 -08:00 committed by Commit Bot
parent 2115d2d268
commit a764999e3f
2 changed files with 5 additions and 71 deletions

View File

@ -14,93 +14,28 @@
namespace webrtc {
typedef void(WINAPI* PInitializeSRWLock)(PSRWLOCK);
typedef void(WINAPI* PAcquireSRWLockExclusive)(PSRWLOCK);
typedef void(WINAPI* PReleaseSRWLockExclusive)(PSRWLOCK);
typedef void(WINAPI* PAcquireSRWLockShared)(PSRWLOCK);
typedef void(WINAPI* PReleaseSRWLockShared)(PSRWLOCK);
PInitializeSRWLock initialize_srw_lock;
PAcquireSRWLockExclusive acquire_srw_lock_exclusive;
PAcquireSRWLockShared acquire_srw_lock_shared;
PReleaseSRWLockShared release_srw_lock_shared;
PReleaseSRWLockExclusive release_srw_lock_exclusive;
RWLockWin::RWLockWin() {
initialize_srw_lock(&lock_);
InitializeSRWLock(&lock_);
}
RWLockWin* RWLockWin::Create() {
if (!LoadModule()) {
return NULL;
}
return new RWLockWin();
}
void RWLockWin::AcquireLockExclusive() {
acquire_srw_lock_exclusive(&lock_);
AcquireSRWLockExclusive(&lock_);
}
void RWLockWin::ReleaseLockExclusive() {
release_srw_lock_exclusive(&lock_);
ReleaseSRWLockExclusive(&lock_);
}
void RWLockWin::AcquireLockShared() {
acquire_srw_lock_shared(&lock_);
AcquireSRWLockShared(&lock_);
}
void RWLockWin::ReleaseLockShared() {
release_srw_lock_shared(&lock_);
}
bool RWLockWin::LoadModule() {
static bool module_load_attempted = false;
static bool native_rw_locks_supported = false;
if (module_load_attempted) {
return native_rw_locks_supported;
}
module_load_attempted = true;
#if !defined(WINUWP)
// Use native implementation if supported (i.e Vista+)
static HMODULE library = LoadLibrary(TEXT("Kernel32.dll"));
if (!library) {
return false;
}
RTC_LOG(LS_VERBOSE) << "Loaded Kernel.dll";
initialize_srw_lock =
(PInitializeSRWLock)GetProcAddress(library, "InitializeSRWLock");
acquire_srw_lock_exclusive = (PAcquireSRWLockExclusive)GetProcAddress(
library, "AcquireSRWLockExclusive");
release_srw_lock_exclusive = (PReleaseSRWLockExclusive)GetProcAddress(
library, "ReleaseSRWLockExclusive");
acquire_srw_lock_shared =
(PAcquireSRWLockShared)GetProcAddress(library, "AcquireSRWLockShared");
release_srw_lock_shared =
(PReleaseSRWLockShared)GetProcAddress(library, "ReleaseSRWLockShared");
if (initialize_srw_lock && acquire_srw_lock_exclusive &&
release_srw_lock_exclusive && acquire_srw_lock_shared &&
release_srw_lock_shared) {
RTC_LOG(LS_VERBOSE) << "Loaded Native RW Lock";
native_rw_locks_supported = true;
}
#else
// On WinUWP the symbols loaded from this library are directly present
// in the headers and thus loading the library is not required (and
// manually loading libraries is restricted due to WinUWP sandboxing).
initialize_srw_lock = InitializeSRWLock;
acquire_srw_lock_exclusive = AcquireSRWLockExclusive;
release_srw_lock_exclusive = ReleaseSRWLockExclusive;
acquire_srw_lock_shared = AcquireSRWLockShared;
release_srw_lock_shared = ReleaseSRWLockShared;
native_rw_locks_supported = true;
#endif // !defined(WINUWP)
return native_rw_locks_supported;
ReleaseSRWLockShared(&lock_);
}
} // namespace webrtc

View File

@ -29,7 +29,6 @@ class RWLockWin : public RWLockWrapper {
private:
RWLockWin();
static bool LoadModule();
SRWLOCK lock_;
};