mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-27 19:12:27 +00:00
Merge master 53ccd8fc5e8a into doc
This commit is contained in:
commit
fb853734e7
@ -64,7 +64,7 @@ need to install them separately.
|
|||||||
|
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
$ *mkdir ~/crashpad*
|
$ *mkdir \~/crashpad*
|
||||||
$ *cd ~/crashpad*
|
$ *cd ~/crashpad*
|
||||||
$ *fetch crashpad*
|
$ *fetch crashpad*
|
||||||
----
|
----
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "client/crashpad_client.h"
|
#include "client/crashpad_client.h"
|
||||||
#include "tools/tool_support.h"
|
#include "tools/tool_support.h"
|
||||||
#include "util/win/critical_section_with_debug_info.h"
|
#include "util/win/critical_section_with_debug_info.h"
|
||||||
|
#include "util/win/get_function.h"
|
||||||
|
|
||||||
namespace crashpad {
|
namespace crashpad {
|
||||||
namespace {
|
namespace {
|
||||||
@ -32,10 +33,8 @@ namespace {
|
|||||||
CRITICAL_SECTION g_test_critical_section;
|
CRITICAL_SECTION g_test_critical_section;
|
||||||
|
|
||||||
ULONG RtlNtStatusToDosError(NTSTATUS status) {
|
ULONG RtlNtStatusToDosError(NTSTATUS status) {
|
||||||
static decltype(::RtlNtStatusToDosError)* rtl_nt_status_to_dos_error =
|
static const auto rtl_nt_status_to_dos_error =
|
||||||
reinterpret_cast<decltype(::RtlNtStatusToDosError)*>(
|
GET_FUNCTION_REQUIRED(L"ntdll.dll", ::RtlNtStatusToDosError);
|
||||||
GetProcAddress(LoadLibrary(L"ntdll.dll"), "RtlNtStatusToDosError"));
|
|
||||||
DCHECK(rtl_nt_status_to_dos_error);
|
|
||||||
return rtl_nt_status_to_dos_error(status);
|
return rtl_nt_status_to_dos_error(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "snapshot/win/process_reader_win.h"
|
#include "snapshot/win/process_reader_win.h"
|
||||||
|
#include "util/win/get_function.h"
|
||||||
|
|
||||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||||
|
|
||||||
@ -30,10 +31,8 @@ BOOL CrashpadGetModuleInformation(HANDLE process,
|
|||||||
HMODULE module,
|
HMODULE module,
|
||||||
MODULEINFO* module_info,
|
MODULEINFO* module_info,
|
||||||
DWORD cb) {
|
DWORD cb) {
|
||||||
static decltype(GetModuleInformation)* get_module_information =
|
static const auto get_module_information =
|
||||||
reinterpret_cast<decltype(GetModuleInformation)*>(
|
GET_FUNCTION_REQUIRED(L"psapi.dll", ::GetModuleInformation);
|
||||||
GetProcAddress(LoadLibrary(L"psapi.dll"), "GetModuleInformation"));
|
|
||||||
DCHECK(get_module_information);
|
|
||||||
return get_module_information(process, module, module_info, cb);
|
return get_module_information(process, module, module_info, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,6 +156,8 @@
|
|||||||
'win/critical_section_with_debug_info.h',
|
'win/critical_section_with_debug_info.h',
|
||||||
'win/exception_handler_server.cc',
|
'win/exception_handler_server.cc',
|
||||||
'win/exception_handler_server.h',
|
'win/exception_handler_server.h',
|
||||||
|
'win/get_function.cc',
|
||||||
|
'win/get_function.h',
|
||||||
'win/module_version.cc',
|
'win/module_version.cc',
|
||||||
'win/module_version.h',
|
'win/module_version.h',
|
||||||
'win/nt_internals.cc',
|
'win/nt_internals.cc',
|
||||||
|
@ -82,6 +82,7 @@
|
|||||||
'win/capture_context_test.cc',
|
'win/capture_context_test.cc',
|
||||||
'win/critical_section_with_debug_info_test.cc',
|
'win/critical_section_with_debug_info_test.cc',
|
||||||
'win/exception_handler_server_test.cc',
|
'win/exception_handler_server_test.cc',
|
||||||
|
'win/get_function_test.cc',
|
||||||
'win/process_info_test.cc',
|
'win/process_info_test.cc',
|
||||||
'win/scoped_process_suspend_test.cc',
|
'win/scoped_process_suspend_test.cc',
|
||||||
'win/time_test.cc',
|
'win/time_test.cc',
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "util/win/critical_section_with_debug_info.h"
|
#include "util/win/critical_section_with_debug_info.h"
|
||||||
|
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
|
#include "util/win/get_function.h"
|
||||||
|
|
||||||
namespace crashpad {
|
namespace crashpad {
|
||||||
|
|
||||||
@ -24,13 +25,8 @@ BOOL CrashpadInitializeCriticalSectionEx(
|
|||||||
CRITICAL_SECTION* critical_section,
|
CRITICAL_SECTION* critical_section,
|
||||||
DWORD spin_count,
|
DWORD spin_count,
|
||||||
DWORD flags) {
|
DWORD flags) {
|
||||||
static decltype(InitializeCriticalSectionEx)* initialize_critical_section_ex =
|
static const auto initialize_critical_section_ex =
|
||||||
reinterpret_cast<decltype(InitializeCriticalSectionEx)*>(GetProcAddress(
|
GET_FUNCTION_REQUIRED(L"kernel32.dll", ::InitializeCriticalSectionEx);
|
||||||
LoadLibrary(L"kernel32.dll"), "InitializeCriticalSectionEx"));
|
|
||||||
if (!initialize_critical_section_ex) {
|
|
||||||
PLOG(ERROR) << "GetProcAddress";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool ret =
|
bool ret =
|
||||||
initialize_critical_section_ex(critical_section, spin_count, flags);
|
initialize_critical_section_ex(critical_section, spin_count, flags);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "util/file/file_writer.h"
|
#include "util/file/file_writer.h"
|
||||||
#include "util/misc/tri_state.h"
|
#include "util/misc/tri_state.h"
|
||||||
#include "util/misc/uuid.h"
|
#include "util/misc/uuid.h"
|
||||||
|
#include "util/win/get_function.h"
|
||||||
#include "util/win/registration_protocol_win.h"
|
#include "util/win/registration_protocol_win.h"
|
||||||
#include "util/win/xp_compat.h"
|
#include "util/win/xp_compat.h"
|
||||||
|
|
||||||
@ -35,10 +36,9 @@ namespace crashpad {
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
decltype(GetNamedPipeClientProcessId)* GetNamedPipeClientProcessIdFunction() {
|
decltype(GetNamedPipeClientProcessId)* GetNamedPipeClientProcessIdFunction() {
|
||||||
static decltype(GetNamedPipeClientProcessId)* func =
|
static const auto get_named_pipe_client_process_id =
|
||||||
reinterpret_cast<decltype(GetNamedPipeClientProcessId)*>(GetProcAddress(
|
GET_FUNCTION(L"kernel32.dll", ::GetNamedPipeClientProcessId);
|
||||||
GetModuleHandle(L"kernel32.dll"), "GetNamedPipeClientProcessId"));
|
return get_named_pipe_client_process_id;
|
||||||
return func;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE DuplicateEvent(HANDLE process, HANDLE event) {
|
HANDLE DuplicateEvent(HANDLE process, HANDLE event) {
|
||||||
|
44
util/win/get_function.cc
Normal file
44
util/win/get_function.cc
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright 2015 The Crashpad Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "util/win/get_function.h"
|
||||||
|
|
||||||
|
#include "base/logging.h"
|
||||||
|
#include "base/strings/utf_string_conversions.h"
|
||||||
|
|
||||||
|
namespace crashpad {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
FARPROC GetFunctionInternal(
|
||||||
|
const wchar_t* library, const char* function, bool required) {
|
||||||
|
HMODULE module = LoadLibrary(library);
|
||||||
|
DPCHECK(!required || module) << "LoadLibrary " << base::UTF16ToUTF8(library);
|
||||||
|
if (!module) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strip off any leading :: that may have come from stringifying the
|
||||||
|
// function’s name.
|
||||||
|
if (function[0] == ':' && function[1] == ':' &&
|
||||||
|
function[2] && function[2] != ':') {
|
||||||
|
function += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
FARPROC proc = GetProcAddress(module, function);
|
||||||
|
DPCHECK(!required || proc) << "GetProcAddress " << function;
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace crashpad
|
121
util/win/get_function.h
Normal file
121
util/win/get_function.h
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
// Copyright 2015 The Crashpad Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#ifndef CRASHPAD_UTIL_WIN_GET_FUNCTION_H_
|
||||||
|
#define CRASHPAD_UTIL_WIN_GET_FUNCTION_H_
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
//! \file
|
||||||
|
|
||||||
|
namespace crashpad {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
//! \brief Returns a function pointer to a named function in a library.
|
||||||
|
//!
|
||||||
|
//! Do not call this directly, use the GET_FUNCTION() or GET_FUNCTION_REQUIRED()
|
||||||
|
//! macros instead.
|
||||||
|
//!
|
||||||
|
//! This accesses \a library by calling `LoadLibrary()` and is subject to the
|
||||||
|
//! same restrictions as that function. Notably, it can’t be used from a
|
||||||
|
//! `DllMain()` entry point.
|
||||||
|
//!
|
||||||
|
//! \param[in] library The library to search in.
|
||||||
|
//! \param[in] function The function to search for. If a leading `::` is
|
||||||
|
//! present, it will be stripped.
|
||||||
|
//! \param[in] required If `true`, require the function to resolve by `DCHECK`.
|
||||||
|
//!
|
||||||
|
//! \return A pointer to the requested function on success. If \a required is
|
||||||
|
//! `true`, triggers a `DCHECK` assertion on failure, otherwise, `nullptr`
|
||||||
|
//! on failure.
|
||||||
|
FARPROC GetFunctionInternal(
|
||||||
|
const wchar_t* library, const char* function, bool required);
|
||||||
|
|
||||||
|
//! \copydoc GetFunctionInternal
|
||||||
|
template <typename FunctionType>
|
||||||
|
FunctionType* GetFunction(
|
||||||
|
const wchar_t* library, const char* function, bool required) {
|
||||||
|
return reinterpret_cast<FunctionType*>(
|
||||||
|
internal::GetFunctionInternal(library, function, required));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace crashpad
|
||||||
|
|
||||||
|
//! \brief Returns a function pointer to a named function in a library without
|
||||||
|
//! requiring that it be found.
|
||||||
|
//!
|
||||||
|
//! If the library or function cannot be found, this will return `nullptr`. This
|
||||||
|
//! macro is intended to be used to access functions that may not be available
|
||||||
|
//! at runtime.
|
||||||
|
//!
|
||||||
|
//! This macro returns a properly-typed function pointer. It is expected to be
|
||||||
|
//! used in this way:
|
||||||
|
//! \code
|
||||||
|
//! static const auto get_named_pipe_client_process_id =
|
||||||
|
//! GET_FUNCTION(L"kernel32.dll", ::GetNamedPipeClientProcessId);
|
||||||
|
//! if (get_named_pipe_client_process_id) {
|
||||||
|
//! BOOL rv = get_named_pipe_client_process_id(pipe, &client_process_id);
|
||||||
|
//! }
|
||||||
|
//! \endcode
|
||||||
|
//!
|
||||||
|
//! This accesses \a library by calling `LoadLibrary()` and is subject to the
|
||||||
|
//! same restrictions as that function. Notably, it can’t be used from a
|
||||||
|
//! `DllMain()` entry point.
|
||||||
|
//!
|
||||||
|
//! \param[in] library The library to search in.
|
||||||
|
//! \param[in] function The function to search for. A leading `::` is
|
||||||
|
//! recommended when a wrapper function of the same name is present.
|
||||||
|
//!
|
||||||
|
//! \return A pointer to the requested function on success, or `nullptr` on
|
||||||
|
//! failure.
|
||||||
|
//!
|
||||||
|
//! \sa GET_FUNCTION_REQUIRED
|
||||||
|
#define GET_FUNCTION(library, function) \
|
||||||
|
crashpad::internal::GetFunction<decltype(function)>( \
|
||||||
|
library, #function, false)
|
||||||
|
|
||||||
|
//! \brief Returns a function pointer to a named function in a library,
|
||||||
|
//! requiring that it be found.
|
||||||
|
//!
|
||||||
|
//! If the library or function cannot be found, this will trigger a `DCHECK`
|
||||||
|
//! assertion. This macro is intended to be used to access functions that are
|
||||||
|
//! always expected to be available at runtime but which are not present in any
|
||||||
|
//! import library.
|
||||||
|
//!
|
||||||
|
//! This macro returns a properly-typed function pointer. It is expected to be
|
||||||
|
//! used in this way:
|
||||||
|
//! \code
|
||||||
|
//! static const auto nt_query_object =
|
||||||
|
//! GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtQueryObject);
|
||||||
|
//! NTSTATUS status =
|
||||||
|
//! nt_query_object(handle, type, &info, info_length, &return_length);
|
||||||
|
//! \endcode
|
||||||
|
//!
|
||||||
|
//! This accesses \a library by calling `LoadLibrary()` and is subject to the
|
||||||
|
//! same restrictions as that function. Notably, it can’t be used from a
|
||||||
|
//! `DllMain()` entry point.
|
||||||
|
//!
|
||||||
|
//! \param[in] library The library to search in.
|
||||||
|
//! \param[in] function The function to search for. A leading `::` is
|
||||||
|
//! recommended when a wrapper function of the same name is present.
|
||||||
|
//!
|
||||||
|
//! \return A pointer to the requested function.
|
||||||
|
//!
|
||||||
|
//! \sa GET_FUNCTION
|
||||||
|
#define GET_FUNCTION_REQUIRED(library, function) \
|
||||||
|
crashpad::internal::GetFunction<decltype(function)>( \
|
||||||
|
library, #function, true)
|
||||||
|
|
||||||
|
#endif // CRASHPAD_UTIL_WIN_GET_FUNCTION_H_
|
78
util/win/get_function_test.cc
Normal file
78
util/win/get_function_test.cc
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
// Copyright 2015 The Crashpad Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "util/win/get_function.h"
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winternl.h>
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
namespace crashpad {
|
||||||
|
namespace test {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
TEST(GetFunction, GetFunction) {
|
||||||
|
// Check equivalence of GET_FUNCTION_REQUIRED() with functions that are
|
||||||
|
// available in the SDK normally.
|
||||||
|
EXPECT_EQ(&GetProcAddress,
|
||||||
|
GET_FUNCTION_REQUIRED(L"kernel32.dll", GetProcAddress));
|
||||||
|
EXPECT_EQ(&LoadLibraryW,
|
||||||
|
GET_FUNCTION_REQUIRED(L"kernel32.dll", LoadLibraryW));
|
||||||
|
|
||||||
|
// Make sure that a function pointer retrieved by GET_FUNCTION_REQUIRED() can
|
||||||
|
// be called and that it works correctly.
|
||||||
|
const auto get_current_process_id =
|
||||||
|
GET_FUNCTION_REQUIRED(L"kernel32.dll", GetCurrentProcessId);
|
||||||
|
EXPECT_EQ(&GetCurrentProcessId, get_current_process_id);
|
||||||
|
ASSERT_TRUE(get_current_process_id);
|
||||||
|
EXPECT_EQ(GetCurrentProcessId(), get_current_process_id());
|
||||||
|
|
||||||
|
// GET_FUNCTION_REQUIRED() and GET_FUNCTION() should behave identically when
|
||||||
|
// the function is present.
|
||||||
|
EXPECT_EQ(get_current_process_id,
|
||||||
|
GET_FUNCTION(L"kernel32.dll", GetCurrentProcessId));
|
||||||
|
|
||||||
|
// Using a leading :: should also work.
|
||||||
|
EXPECT_EQ(get_current_process_id,
|
||||||
|
GET_FUNCTION(L"kernel32.dll", ::GetCurrentProcessId));
|
||||||
|
EXPECT_EQ(get_current_process_id,
|
||||||
|
GET_FUNCTION_REQUIRED(L"kernel32.dll", ::GetCurrentProcessId));
|
||||||
|
|
||||||
|
// Try a function that’s declared in the SDK’s headers but that has no import
|
||||||
|
// library.
|
||||||
|
EXPECT_TRUE(GET_FUNCTION_REQUIRED(L"ntdll.dll", RtlNtStatusToDosError));
|
||||||
|
|
||||||
|
// GetNamedPipeClientProcessId() is only available on Vista and later.
|
||||||
|
const auto get_named_pipe_client_process_id =
|
||||||
|
GET_FUNCTION(L"kernel32.dll", GetNamedPipeClientProcessId);
|
||||||
|
const DWORD version = GetVersion();
|
||||||
|
const DWORD major_version = LOBYTE(LOWORD(version));
|
||||||
|
EXPECT_EQ(major_version >= 6, get_named_pipe_client_process_id != nullptr);
|
||||||
|
|
||||||
|
// Test that GET_FUNCTION() can fail by trying a nonexistent library and a
|
||||||
|
// symbol that doesn’t exist in the specified library.
|
||||||
|
EXPECT_FALSE(GET_FUNCTION(L"not_a_real_library.dll", TerminateProcess));
|
||||||
|
EXPECT_FALSE(GET_FUNCTION(L"ntdll.dll", TerminateProcess));
|
||||||
|
EXPECT_FALSE(GET_FUNCTION(L"not_a_real_library.dll", ::TerminateProcess));
|
||||||
|
EXPECT_FALSE(GET_FUNCTION(L"ntdll.dll", ::TerminateProcess));
|
||||||
|
|
||||||
|
// Here it is!
|
||||||
|
EXPECT_TRUE(GET_FUNCTION(L"kernel32.dll", TerminateProcess));
|
||||||
|
EXPECT_TRUE(GET_FUNCTION(L"kernel32.dll", ::TerminateProcess));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace test
|
||||||
|
} // namespace crashpad
|
@ -15,6 +15,16 @@
|
|||||||
#include "util/win/nt_internals.h"
|
#include "util/win/nt_internals.h"
|
||||||
|
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
|
#include "util/win/get_function.h"
|
||||||
|
|
||||||
|
// Declarations that the system headers should provide but don’t.
|
||||||
|
|
||||||
|
struct CLIENT_ID;
|
||||||
|
|
||||||
|
NTSTATUS NTAPI NtOpenThread(HANDLE* ThreadHandle,
|
||||||
|
ACCESS_MASK DesiredAccess,
|
||||||
|
OBJECT_ATTRIBUTES* ObjectAttributes,
|
||||||
|
CLIENT_ID* ClientId);
|
||||||
|
|
||||||
namespace crashpad {
|
namespace crashpad {
|
||||||
|
|
||||||
@ -23,10 +33,8 @@ NTSTATUS NtQuerySystemInformation(
|
|||||||
PVOID system_information,
|
PVOID system_information,
|
||||||
ULONG system_information_length,
|
ULONG system_information_length,
|
||||||
PULONG return_length) {
|
PULONG return_length) {
|
||||||
static decltype(::NtQuerySystemInformation)* nt_query_system_information =
|
static const auto nt_query_system_information =
|
||||||
reinterpret_cast<decltype(::NtQuerySystemInformation)*>(GetProcAddress(
|
GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtQuerySystemInformation);
|
||||||
LoadLibrary(L"ntdll.dll"), "NtQuerySystemInformation"));
|
|
||||||
DCHECK(nt_query_system_information);
|
|
||||||
return nt_query_system_information(system_information_class,
|
return nt_query_system_information(system_information_class,
|
||||||
system_information,
|
system_information,
|
||||||
system_information_length,
|
system_information_length,
|
||||||
@ -38,10 +46,8 @@ NTSTATUS NtQueryInformationThread(HANDLE thread_handle,
|
|||||||
PVOID thread_information,
|
PVOID thread_information,
|
||||||
ULONG thread_information_length,
|
ULONG thread_information_length,
|
||||||
PULONG return_length) {
|
PULONG return_length) {
|
||||||
static decltype(::NtQueryInformationThread)* nt_query_information_thread =
|
static const auto nt_query_information_thread =
|
||||||
reinterpret_cast<decltype(::NtQueryInformationThread)*>(GetProcAddress(
|
GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtQueryInformationThread);
|
||||||
LoadLibrary(L"ntdll.dll"), "NtQueryInformationThread"));
|
|
||||||
DCHECK(nt_query_information_thread);
|
|
||||||
return nt_query_information_thread(thread_handle,
|
return nt_query_information_thread(thread_handle,
|
||||||
thread_information_class,
|
thread_information_class,
|
||||||
thread_information,
|
thread_information,
|
||||||
@ -49,27 +55,18 @@ NTSTATUS NtQueryInformationThread(HANDLE thread_handle,
|
|||||||
return_length);
|
return_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The 4th argument is CLIENT_ID*, but as we can't typedef that, we simply cast
|
|
||||||
// to void* here.
|
|
||||||
typedef NTSTATUS(WINAPI* NtOpenThreadFunction)(
|
|
||||||
PHANDLE ThreadHandle,
|
|
||||||
ACCESS_MASK DesiredAccess,
|
|
||||||
POBJECT_ATTRIBUTES ObjectAttributes,
|
|
||||||
const void* ClientId);
|
|
||||||
|
|
||||||
template <class Traits>
|
template <class Traits>
|
||||||
NTSTATUS NtOpenThread(PHANDLE thread_handle,
|
NTSTATUS NtOpenThread(PHANDLE thread_handle,
|
||||||
ACCESS_MASK desired_access,
|
ACCESS_MASK desired_access,
|
||||||
POBJECT_ATTRIBUTES object_attributes,
|
POBJECT_ATTRIBUTES object_attributes,
|
||||||
const process_types::CLIENT_ID<Traits>* client_id) {
|
const process_types::CLIENT_ID<Traits>* client_id) {
|
||||||
static NtOpenThreadFunction nt_open_thread =
|
static const auto nt_open_thread =
|
||||||
reinterpret_cast<NtOpenThreadFunction>(
|
GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtOpenThread);
|
||||||
GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtOpenThread"));
|
return nt_open_thread(
|
||||||
DCHECK(nt_open_thread);
|
thread_handle,
|
||||||
return nt_open_thread(thread_handle,
|
desired_access,
|
||||||
desired_access,
|
object_attributes,
|
||||||
object_attributes,
|
const_cast<CLIENT_ID*>(reinterpret_cast<const CLIENT_ID*>(client_id)));
|
||||||
static_cast<const void*>(client_id));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NtQueryObject(HANDLE handle,
|
NTSTATUS NtQueryObject(HANDLE handle,
|
||||||
@ -77,10 +74,8 @@ NTSTATUS NtQueryObject(HANDLE handle,
|
|||||||
void* object_information,
|
void* object_information,
|
||||||
ULONG object_information_length,
|
ULONG object_information_length,
|
||||||
ULONG* return_length) {
|
ULONG* return_length) {
|
||||||
static decltype(::NtQueryObject)* nt_query_object =
|
static const auto nt_query_object =
|
||||||
reinterpret_cast<decltype(::NtQueryObject)*>(
|
GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtQueryObject);
|
||||||
GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtQueryObject"));
|
|
||||||
DCHECK(nt_query_object);
|
|
||||||
return nt_query_object(handle,
|
return nt_query_object(handle,
|
||||||
object_information_class,
|
object_information_class,
|
||||||
object_information,
|
object_information,
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "base/template_util.h"
|
#include "base/template_util.h"
|
||||||
#include "build/build_config.h"
|
#include "build/build_config.h"
|
||||||
#include "util/numeric/safe_assignment.h"
|
#include "util/numeric/safe_assignment.h"
|
||||||
|
#include "util/win/get_function.h"
|
||||||
#include "util/win/nt_internals.h"
|
#include "util/win/nt_internals.h"
|
||||||
#include "util/win/ntstatus_logging.h"
|
#include "util/win/ntstatus_logging.h"
|
||||||
#include "util/win/process_structs.h"
|
#include "util/win/process_structs.h"
|
||||||
@ -39,10 +40,8 @@ NTSTATUS NtQueryInformationProcess(HANDLE process_handle,
|
|||||||
PVOID process_information,
|
PVOID process_information,
|
||||||
ULONG process_information_length,
|
ULONG process_information_length,
|
||||||
PULONG return_length) {
|
PULONG return_length) {
|
||||||
static decltype(::NtQueryInformationProcess)* nt_query_information_process =
|
static const auto nt_query_information_process =
|
||||||
reinterpret_cast<decltype(::NtQueryInformationProcess)*>(GetProcAddress(
|
GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtQueryInformationProcess);
|
||||||
LoadLibrary(L"ntdll.dll"), "NtQueryInformationProcess"));
|
|
||||||
DCHECK(nt_query_information_process);
|
|
||||||
return nt_query_information_process(process_handle,
|
return nt_query_information_process(process_handle,
|
||||||
process_information_class,
|
process_information_class,
|
||||||
process_information,
|
process_information,
|
||||||
@ -51,9 +50,8 @@ NTSTATUS NtQueryInformationProcess(HANDLE process_handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool IsProcessWow64(HANDLE process_handle) {
|
bool IsProcessWow64(HANDLE process_handle) {
|
||||||
static decltype(IsWow64Process)* is_wow64_process =
|
static const auto is_wow64_process =
|
||||||
reinterpret_cast<decltype(IsWow64Process)*>(
|
GET_FUNCTION(L"kernel32.dll", ::IsWow64Process);
|
||||||
GetProcAddress(LoadLibrary(L"kernel32.dll"), "IsWow64Process"));
|
|
||||||
if (!is_wow64_process)
|
if (!is_wow64_process)
|
||||||
return false;
|
return false;
|
||||||
BOOL is_wow64;
|
BOOL is_wow64;
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "test/win/child_launcher.h"
|
#include "test/win/child_launcher.h"
|
||||||
#include "util/file/file_io.h"
|
#include "util/file/file_io.h"
|
||||||
#include "util/misc/uuid.h"
|
#include "util/misc/uuid.h"
|
||||||
|
#include "util/win/get_function.h"
|
||||||
#include "util/win/scoped_handle.h"
|
#include "util/win/scoped_handle.h"
|
||||||
|
|
||||||
namespace crashpad {
|
namespace crashpad {
|
||||||
@ -40,9 +41,8 @@ namespace {
|
|||||||
const wchar_t kNtdllName[] = L"\\ntdll.dll";
|
const wchar_t kNtdllName[] = L"\\ntdll.dll";
|
||||||
|
|
||||||
bool IsProcessWow64(HANDLE process_handle) {
|
bool IsProcessWow64(HANDLE process_handle) {
|
||||||
static decltype(IsWow64Process)* is_wow64_process =
|
static const auto is_wow64_process =
|
||||||
reinterpret_cast<decltype(IsWow64Process)*>(
|
GET_FUNCTION(L"kernel32.dll", ::IsWow64Process);
|
||||||
GetProcAddress(LoadLibrary(L"kernel32.dll"), "IsWow64Process"));
|
|
||||||
if (!is_wow64_process)
|
if (!is_wow64_process)
|
||||||
return false;
|
return false;
|
||||||
BOOL is_wow64;
|
BOOL is_wow64;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user