// Copyright 2015 The Crashpad Authors // // 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 //! \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 FunctionType* GetFunction( const wchar_t* library, const char* function, bool required) { return reinterpret_cast( 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( \ 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( \ library, #function, true) #endif // CRASHPAD_UTIL_WIN_GET_FUNCTION_H_