Index: util/win/get_function_test.cc |
diff --git a/util/win/get_function_test.cc b/util/win/get_function_test.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a2217aef66ba35b90aa6afe043031bdf0c8d2694 |
--- /dev/null |
+++ b/util/win/get_function_test.cc |
@@ -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 |