1 // Copyright 2010 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/win/win_util.h"
6
7 #include <objbase.h>
8
9 #include <string_view>
10
11 #include "base/containers/contains.h"
12 #include "base/files/file_path.h"
13 #include "base/scoped_native_library.h"
14 #include "base/strings/string_util.h"
15 #include "base/win/scoped_co_mem.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 namespace base {
19 namespace win {
20
21 namespace {
22
23 // Saves the current thread's locale ID when initialized, and restores it when
24 // the instance is going out of scope.
25 class ThreadLocaleSaver {
26 public:
ThreadLocaleSaver()27 ThreadLocaleSaver() : original_locale_id_(GetThreadLocale()) {}
28
29 ThreadLocaleSaver(const ThreadLocaleSaver&) = delete;
30 ThreadLocaleSaver& operator=(const ThreadLocaleSaver&) = delete;
31
~ThreadLocaleSaver()32 ~ThreadLocaleSaver() { SetThreadLocale(original_locale_id_); }
33
34 private:
35 LCID original_locale_id_;
36 };
37
38 } // namespace
39
40 // The test is somewhat silly, because some bots some have UAC enabled and some
41 // have it disabled. At least we check that it does not crash.
TEST(BaseWinUtilTest,TestIsUACEnabled)42 TEST(BaseWinUtilTest, TestIsUACEnabled) {
43 UserAccountControlIsEnabled();
44 }
45
TEST(BaseWinUtilTest,TestGetUserSidString)46 TEST(BaseWinUtilTest, TestGetUserSidString) {
47 std::wstring user_sid;
48 EXPECT_TRUE(GetUserSidString(&user_sid));
49 EXPECT_TRUE(!user_sid.empty());
50 }
51
TEST(BaseWinUtilTest,TestGetLoadedModulesSnapshot)52 TEST(BaseWinUtilTest, TestGetLoadedModulesSnapshot) {
53 std::vector<HMODULE> snapshot;
54
55 ASSERT_TRUE(GetLoadedModulesSnapshot(::GetCurrentProcess(), &snapshot));
56 size_t original_snapshot_size = snapshot.size();
57 ASSERT_GT(original_snapshot_size, 0u);
58 snapshot.clear();
59
60 // Load in a new module. Pick zipfldr.dll as it is present from WinXP to
61 // Win10, including ARM64 Win10, and yet rarely used.
62 const FilePath::CharType dll_name[] = FILE_PATH_LITERAL("zipfldr.dll");
63 ASSERT_EQ(nullptr, ::GetModuleHandle(dll_name));
64
65 ScopedNativeLibrary new_dll((FilePath(dll_name)));
66 ASSERT_NE(static_cast<HMODULE>(nullptr), new_dll.get());
67 ASSERT_TRUE(GetLoadedModulesSnapshot(::GetCurrentProcess(), &snapshot));
68 ASSERT_GT(snapshot.size(), original_snapshot_size);
69 ASSERT_TRUE(Contains(snapshot, new_dll.get()));
70 }
71
TEST(BaseWinUtilTest,TestUint32ToInvalidHandle)72 TEST(BaseWinUtilTest, TestUint32ToInvalidHandle) {
73 // Ensure that INVALID_HANDLE_VALUE is preserved when going to a 32-bit value
74 // and back on 64-bit platforms.
75 uint32_t invalid_handle = HandleToUint32(INVALID_HANDLE_VALUE);
76 EXPECT_EQ(INVALID_HANDLE_VALUE, Uint32ToHandle(invalid_handle));
77 }
78
TEST(BaseWinUtilTest,WStringFromGUID)79 TEST(BaseWinUtilTest, WStringFromGUID) {
80 const GUID kGuid = {0x7698f759,
81 0xf5b0,
82 0x4328,
83 {0x92, 0x38, 0xbd, 0x70, 0x8a, 0x6d, 0xc9, 0x63}};
84 const std::wstring_view kGuidStr = L"{7698F759-F5B0-4328-9238-BD708A6DC963}";
85 auto guid_wstring = WStringFromGUID(kGuid);
86 EXPECT_EQ(guid_wstring, kGuidStr);
87 wchar_t guid_wchar[39];
88 ::StringFromGUID2(kGuid, guid_wchar, std::size(guid_wchar));
89 EXPECT_STREQ(guid_wstring.c_str(), guid_wchar);
90 ScopedCoMem<OLECHAR> clsid_string;
91 ::StringFromCLSID(kGuid, &clsid_string);
92 EXPECT_STREQ(guid_wstring.c_str(), clsid_string.get());
93 }
94
TEST(BaseWinUtilTest,GetWindowObjectName)95 TEST(BaseWinUtilTest, GetWindowObjectName) {
96 std::wstring created_desktop_name(L"test_desktop");
97 HDESK desktop_handle =
98 ::CreateDesktop(created_desktop_name.c_str(), nullptr, nullptr, 0,
99 DESKTOP_CREATEWINDOW | DESKTOP_READOBJECTS |
100 READ_CONTROL | WRITE_DAC | WRITE_OWNER,
101 nullptr);
102
103 ASSERT_NE(desktop_handle, nullptr);
104 EXPECT_EQ(created_desktop_name, GetWindowObjectName(desktop_handle));
105 ASSERT_TRUE(::CloseDesktop(desktop_handle));
106 }
107
TEST(BaseWinUtilTest,IsRunningUnderDesktopName)108 TEST(BaseWinUtilTest, IsRunningUnderDesktopName) {
109 HDESK thread_desktop = ::GetThreadDesktop(::GetCurrentThreadId());
110
111 ASSERT_NE(thread_desktop, nullptr);
112 std::wstring desktop_name = GetWindowObjectName(thread_desktop);
113
114 EXPECT_TRUE(IsRunningUnderDesktopName(desktop_name));
115 EXPECT_TRUE(IsRunningUnderDesktopName(
116 AsWString(ToLowerASCII(AsStringPiece16(desktop_name)))));
117 EXPECT_TRUE(IsRunningUnderDesktopName(
118 AsWString(ToUpperASCII(AsStringPiece16(desktop_name)))));
119 EXPECT_FALSE(
120 IsRunningUnderDesktopName(desktop_name + L"_non_existent_desktop_name"));
121 }
122
123 } // namespace win
124 } // namespace base
125