| // Copyright 2003-2009 Google Inc. |
| // |
| // 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 <ATLComTime.h> |
| #include <atltypes.h> |
| #include <atlwin.h> |
| #include <map> |
| #include <vector> |
| #include "omaha/common/app_util.h" |
| #include "omaha/common/constants.h" |
| #include "omaha/common/dynamic_link_kernel32.h" |
| #include "omaha/common/file.h" |
| #include "omaha/common/module_utils.h" |
| #include "omaha/common/path.h" |
| #include "omaha/common/shell.h" |
| #include "omaha/common/string.h" |
| #include "omaha/common/time.h" |
| #include "omaha/common/utils.h" |
| #include "omaha/common/scoped_any.h" |
| #include "omaha/common/system_info.h" |
| #include "omaha/common/vistautil.h" |
| #include "omaha/testing/unit_test.h" |
| |
| namespace omaha { |
| |
| // Make sure that the time functions work. |
| TEST(UtilsTest, Time) { |
| // TODO(omaha): - add a test from string to time and back again. |
| // Further test the time converters. |
| time64 now = GetCurrent100NSTime(); |
| ASSERT_TRUE(StringToTime(TimeToString(now)) == now); |
| |
| // Test GetTimeCategory. |
| ASSERT_EQ(PAST, |
| GetTimeCategory(static_cast<time64>(0))); |
| ASSERT_EQ(PRESENT, |
| GetTimeCategory(static_cast<time64>(now))); |
| ASSERT_EQ(PRESENT, |
| GetTimeCategory(static_cast<time64>(now - kDaysTo100ns))); |
| ASSERT_EQ(PRESENT, |
| GetTimeCategory(static_cast<time64>(now - 365 * kDaysTo100ns))); |
| // A little bit in the future is also considered present. |
| ASSERT_EQ(PRESENT, |
| GetTimeCategory(static_cast<time64>(now + kDaysTo100ns))); |
| ASSERT_EQ(PRESENT, |
| GetTimeCategory(static_cast<time64>( |
| now - 30 * 365 * kDaysTo100ns))); |
| ASSERT_EQ(PAST, |
| GetTimeCategory(static_cast<time64>( |
| now - 50 * 365 * kDaysTo100ns))); |
| ASSERT_EQ(FUTURE, |
| GetTimeCategory(static_cast<time64>(now + kDaysTo100ns * 6))); |
| ASSERT_EQ(FUTURE, |
| GetTimeCategory(static_cast<time64>(now + 365 * kDaysTo100ns))); |
| |
| // Test IsValidTime. |
| ASSERT_FALSE(IsValidTime(static_cast<time64>(0))); |
| ASSERT_TRUE(IsValidTime(static_cast<time64>(now))); |
| ASSERT_TRUE(IsValidTime(static_cast<time64>(now - 365 * kDaysTo100ns))); |
| ASSERT_TRUE(IsValidTime(static_cast<time64>(now - 10 * 365 * kDaysTo100ns))); |
| ASSERT_TRUE(IsValidTime(static_cast<time64>(now + kDaysTo100ns))); |
| ASSERT_FALSE(IsValidTime(static_cast<time64>(now - 50 * 365 * kDaysTo100ns))); |
| ASSERT_FALSE(IsValidTime(static_cast<time64>(now + 50 * 365 * kDaysTo100ns))); |
| ASSERT_FALSE(IsValidTime(static_cast<time64>(now + kDaysTo100ns * 6))); |
| } |
| |
| TEST(UtilsTest, GetFolderPath_Success) { |
| CString path; |
| EXPECT_SUCCEEDED(GetFolderPath(CSIDL_PROGRAM_FILES, &path)); |
| BOOL isWow64 = FALSE; |
| EXPECT_SUCCEEDED(Kernel32::IsWow64Process(GetCurrentProcess(), &isWow64)); |
| CString expected_path = isWow64 ? |
| _T("C:\\Program Files (x86)") : _T("C:\\Program Files"); |
| EXPECT_STREQ(expected_path, path); |
| } |
| |
| TEST(UtilsTest, GetFolderPath_Errors) { |
| CString path; |
| EXPECT_EQ(E_INVALIDARG, GetFolderPath(0x7fff, &path)); |
| EXPECT_TRUE(path.IsEmpty()); |
| EXPECT_EQ(E_INVALIDARG, GetFolderPath(CSIDL_PROGRAM_FILES, NULL)); |
| } |
| |
| TEST(UtilsTest, CallEntryPoint0) { |
| HRESULT hr(E_FAIL); |
| ASSERT_FAILED(CallEntryPoint0(L"random-nonsense.dll", "foobar", &hr)); |
| } |
| |
| TEST(UtilsTest, ReadEntireFile) { |
| TCHAR directory[MAX_PATH] = {0}; |
| ASSERT_TRUE(GetModuleDirectory(NULL, directory)); |
| CString file_name; |
| file_name.AppendFormat(_T("%s\\declaration.txt"), directory); |
| |
| std::vector<byte> buffer; |
| ASSERT_FAILED(ReadEntireFile(L"C:\\F00Bar\\ImaginaryFile", 0, &buffer)); |
| |
| ASSERT_SUCCEEDED(ReadEntireFile(file_name, 0, &buffer)); |
| ASSERT_EQ(9405, buffer.size()); |
| buffer.resize(0); |
| ASSERT_FAILED(ReadEntireFile(L"C:\\WINDOWS\\Greenstone.bmp", 1000, &buffer)); |
| } |
| |
| // TODO(omaha): Need a test for WriteEntireFile |
| // TEST(UtilsTest, WriteEntireFile) { |
| // } |
| |
| TEST(UtilsTest, RegSplitKeyvalueName) { |
| CString key_name, value_name; |
| ASSERT_SUCCEEDED(RegSplitKeyvalueName(CString(L"HKLM\\Foo\\"), |
| &key_name, |
| &value_name)); |
| ASSERT_STREQ(key_name, L"HKLM\\Foo"); |
| ASSERT_TRUE(value_name.IsEmpty()); |
| |
| ASSERT_SUCCEEDED(RegSplitKeyvalueName(CString(L"HKLM\\Foo\\(default)"), |
| &key_name, |
| &value_name)); |
| ASSERT_STREQ(key_name, L"HKLM\\Foo"); |
| ASSERT_TRUE(value_name.IsEmpty()); |
| |
| ASSERT_SUCCEEDED(RegSplitKeyvalueName(CString(L"HKLM\\Foo\\Bar"), |
| &key_name, |
| &value_name)); |
| ASSERT_STREQ(key_name, L"HKLM\\Foo"); |
| ASSERT_STREQ(value_name, L"Bar"); |
| } |
| |
| TEST(UtilsTest, ExpandEnvLikeStrings) { |
| std::map<CString, CString> mapping; |
| ASSERT_SUCCEEDED(Shell::GetSpecialFolderKeywordsMapping(&mapping)); |
| |
| CString out; |
| ASSERT_SUCCEEDED(ExpandEnvLikeStrings( |
| L"Foo%WINDOWS%Bar%SYSTEM%Zebra%WINDOWS%%SYSTEM%", mapping, &out)); |
| |
| // This should work, but CmpHelperSTRCASEEQ is not overloaded for wchars. |
| // ASSERT_STRCASEEQ(out, L"FooC:\\WINDOWSBarC:\\WINDOWS\\system32Zebra" |
| // L"C:\\WINDOWSC:\\WINDOWS\\system32"); |
| ASSERT_EQ(out.CompareNoCase(L"FooC:\\WINDOWSBarC:\\WINDOWS\\system32Zebra" |
| L"C:\\WINDOWSC:\\WINDOWS\\system32"), |
| 0); |
| ASSERT_FAILED(ExpandEnvLikeStrings(L"Foo%WINDOWS%%BAR%Zebra", mapping, &out)); |
| } |
| |
| TEST(UtilsTest, GetCurrentProcessHandle) { |
| scoped_process proc; |
| ASSERT_SUCCEEDED(GetCurrentProcessHandle(address(proc))); |
| ASSERT_TRUE(valid(proc)); |
| } |
| |
| TEST(UtilsTest, IsGuid) { |
| ASSERT_FALSE(IsGuid(NULL)); |
| ASSERT_FALSE(IsGuid(_T(""))); |
| ASSERT_FALSE(IsGuid(_T("{}"))); |
| ASSERT_FALSE(IsGuid(_T("a"))); |
| ASSERT_FALSE(IsGuid(_T("CA3045BFA6B14fb8A0EFA615CEFE452C"))); |
| |
| // Missing {} |
| ASSERT_FALSE(IsGuid(_T("CA3045BF-A6B1-4fb8-A0EF-A615CEFE452C"))); |
| |
| // Invalid char X |
| ASSERT_FALSE(IsGuid(_T("{XA3045BF-A6B1-4fb8-A0EF-A615CEFE452C}"))); |
| |
| // Invalid binary char 0x200 |
| ASSERT_FALSE(IsGuid(_T("{\0x200a3045bf-a6b1-4fb8-a0ef-a615cefe452c}"))); |
| |
| // Missing - |
| ASSERT_FALSE(IsGuid(_T("{CA3045BFA6B14fb8A0EFA615CEFE452C}"))); |
| |
| // Double quotes |
| ASSERT_FALSE(IsGuid(_T("\"{ca3045bf-a6b1-4fb8-a0ef-a615cefe452c}\""))); |
| |
| ASSERT_TRUE(IsGuid(_T("{00000000-0000-0000-0000-000000000000}"))); |
| ASSERT_TRUE(IsGuid(_T("{CA3045BF-A6B1-4fb8-A0EF-A615CEFE452C}"))); |
| ASSERT_TRUE(IsGuid(_T("{ca3045bf-a6b1-4fb8-a0ef-a615cefe452c}"))); |
| } |
| |
| TEST(UtilsTest, VersionFromString_ValidVersion) { |
| EXPECT_EQ(MAKEDLLVERULL(42, 1, 21, 12345), |
| VersionFromString(_T("42.1.21.12345"))); |
| } |
| |
| TEST(UtilsTest, VersionFromString_VersionZero) { |
| EXPECT_EQ(0, VersionFromString(_T("0.0.0.0"))); |
| } |
| |
| TEST(UtilsTest, VersionFromString_VersionUpperLimits) { |
| EXPECT_EQ(MAKEDLLVERULL(0xffff, 0xffff, 0xffff, 0xffff), |
| VersionFromString(_T("65535.65535.65535.65535"))); |
| EXPECT_EQ(0, VersionFromString(_T("65536.65536.65536.65536"))); |
| EXPECT_EQ(0, VersionFromString(_T("1.2.65536.65536"))); |
| } |
| |
| TEST(UtilsTest, VersionFromString_IntegerOverflow) { |
| EXPECT_EQ(0, VersionFromString(_T("1.2.3.4294967296"))); |
| } |
| |
| TEST(UtilsTest, VersionFromString_NegativeVersion) { |
| EXPECT_EQ(0, VersionFromString(_T("1.2.3.-22"))); |
| } |
| |
| TEST(UtilsTest, VersionFromString_TooFewElements) { |
| EXPECT_EQ(0, VersionFromString(_T("1.1.1"))); |
| } |
| |
| TEST(UtilsTest, VersionFromString_ExtraPeriod) { |
| EXPECT_EQ(0, VersionFromString(_T("1.1.2.3."))); |
| } |
| |
| TEST(UtilsTest, VersionFromString_TooManyElements) { |
| EXPECT_EQ(0, VersionFromString(_T("1.1.2.3.4"))); |
| } |
| |
| TEST(UtilsTest, VersionFromString_Char) { |
| EXPECT_EQ(0, VersionFromString(_T("1.B.3.4"))); |
| EXPECT_EQ(0, VersionFromString(_T("1.2.3.B"))); |
| EXPECT_EQ(0, VersionFromString(_T("1.2.3.9B"))); |
| } |
| |
| TEST(UtilsTest, StringFromVersion_ValidVersion) { |
| EXPECT_STREQ(_T("42.1.21.12345"), |
| StringFromVersion(MAKEDLLVERULL(42, 1, 21, 12345))); |
| } |
| |
| TEST(UtilsTest, StringFromVersion_VersionZero) { |
| EXPECT_STREQ(_T("0.0.0.0"), StringFromVersion(0)); |
| } |
| |
| TEST(UtilsTest, StringFromVersion_VersionUpperLimits) { |
| EXPECT_STREQ( |
| _T("65535.65535.65535.65535"), |
| StringFromVersion(MAKEDLLVERULL(0xffff, 0xffff, 0xffff, 0xffff))); |
| } |
| |
| TEST(UtilsTest, IsLocalSystemSid) { |
| EXPECT_TRUE(IsLocalSystemSid(kLocalSystemSid)); |
| EXPECT_TRUE(IsLocalSystemSid(_T("S-1-5-18"))); |
| EXPECT_TRUE(IsLocalSystemSid(_T("s-1-5-18"))); |
| |
| EXPECT_FALSE(IsLocalSystemSid(_T(""))); |
| EXPECT_FALSE(IsLocalSystemSid(_T("S-1-5-17"))); |
| } |
| |
| // There is a very small probability the test could fail. |
| TEST(UtilsTest, GenRandom) { |
| int random_int = 0; |
| EXPECT_TRUE(GenRandom(&random_int, sizeof(random_int))); |
| EXPECT_NE(random_int, 0); |
| |
| int another_random_int = 0; |
| EXPECT_TRUE(GenRandom(&another_random_int, sizeof(another_random_int))); |
| EXPECT_NE(another_random_int, 0); |
| |
| EXPECT_NE(random_int, another_random_int); |
| } |
| |
| // Counts instances of the class. |
| class Counter { |
| public: |
| Counter() { |
| ++instance_count_; |
| } |
| ~Counter() { |
| --instance_count_; |
| } |
| static int instance_count() { return instance_count_; } |
| private: |
| static int instance_count_; |
| DISALLOW_EVIL_CONSTRUCTORS(Counter); |
| }; |
| |
| int Counter::instance_count_ = 0; |
| |
| // Checks if the functor is actually calling the destructor of the type. |
| TEST(UtilsTest, DeleteFun) { |
| EXPECT_EQ(Counter::instance_count(), 0); |
| Counter* counter = new Counter; |
| EXPECT_EQ(Counter::instance_count(), 1); |
| DeleteFun().operator()(counter); |
| EXPECT_EQ(Counter::instance_count(), 0); |
| |
| // Checks if the template can be instantiated for some common built in types. |
| int* pointer_int = NULL; |
| DeleteFun().operator()(pointer_int); |
| |
| const char* pointer_char = NULL; |
| DeleteFun().operator()(pointer_char); |
| } |
| |
| TEST(UtilsTest, IsUserLoggedOn) { |
| bool is_logged_on(false); |
| ASSERT_HRESULT_SUCCEEDED(IsUserLoggedOn(&is_logged_on)); |
| ASSERT_TRUE(is_logged_on); |
| } |
| |
| TEST(UtilsTest, IsClickOnceDisabled) { |
| EXPECT_FALSE(IsClickOnceDisabled()); |
| } |
| |
| TEST(UtilsTest, ConfigureRunAtStartup) { |
| const TCHAR kRunKeyPath[] = |
| _T("HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"); |
| |
| RegKey::DeleteKey(kRegistryHiveOverrideRoot, true); |
| OverrideRegistryHives(kRegistryHiveOverrideRoot); |
| |
| EXPECT_FALSE(RegKey::HasKey(kRunKeyPath)); |
| |
| EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), |
| ConfigureRunAtStartup(USER_KEY_NAME, _T("FooApp"), |
| _T("\"foo.exe\""), false)); |
| EXPECT_FALSE(RegKey::HasKey(kRunKeyPath)); |
| |
| EXPECT_SUCCEEDED(ConfigureRunAtStartup(USER_KEY_NAME, _T("FooApp"), |
| _T("\"C:\\foo.exe\" /x"), true)); |
| CString value; |
| EXPECT_SUCCEEDED(RegKey::GetValue(kRunKeyPath, _T("FooApp"), &value)); |
| EXPECT_STREQ(_T("\"C:\\foo.exe\" /x"), value); |
| |
| EXPECT_SUCCEEDED(ConfigureRunAtStartup(USER_KEY_NAME, _T("FooApp"), |
| _T("\"foo.exe\""), false)); |
| EXPECT_FALSE(RegKey::HasValue(kRunKeyPath, _T("FooApp"))); |
| EXPECT_TRUE(RegKey::HasKey(kRunKeyPath)); |
| |
| RestoreRegistryHives(); |
| EXPECT_SUCCEEDED(RegKey::DeleteKey(kRegistryHiveOverrideRoot, true)); |
| } |
| |
| TEST(UtilsTest, ValidPath) { |
| CString cmd_line = |
| _T("\"C:\\Program Files\\Internet Explorer\\iexplore.exe\" -nohome"); |
| CString exe_path; |
| EXPECT_SUCCEEDED(GetExePathFromCommandLine(cmd_line, &exe_path)); |
| EXPECT_STREQ(_T("C:\\Program Files\\Internet Explorer\\iexplore.exe"), |
| exe_path); |
| } |
| |
| TEST(UtilsTest, InvalidPath) { |
| CString cmd_line = _T(""); |
| CString exe_path; |
| EXPECT_FAILED(GetExePathFromCommandLine(cmd_line, &exe_path)); |
| EXPECT_TRUE(exe_path.IsEmpty()); |
| } |
| |
| TEST(UtilsTest, PinModuleIntoProcess) { |
| const TCHAR module_name[] = _T("icmp.dll"); |
| const void* kNullModule = NULL; |
| |
| // The module should not be loaded at this time. |
| EXPECT_EQ(kNullModule, ::GetModuleHandle(module_name)); |
| |
| // Loads and unloads the module. |
| { |
| scoped_library module(::LoadLibrary(module_name)); |
| EXPECT_TRUE(module); |
| EXPECT_NE(kNullModule, ::GetModuleHandle(module_name)); |
| } |
| EXPECT_EQ(kNullModule, ::GetModuleHandle(module_name)); |
| |
| // Loads, pins, and unloads the module. |
| { |
| scoped_library module(::LoadLibrary(module_name)); |
| EXPECT_TRUE(module); |
| EXPECT_NE(kNullModule, ::GetModuleHandle(module_name)); |
| PinModuleIntoProcess(module_name); |
| } |
| EXPECT_NE(kNullModule, ::GetModuleHandle(module_name)); |
| } |
| |
| // Assumes Windows is installed on the C: drive. |
| TEST(UtilsTest, GetEnvironmentVariableAsString) { |
| EXPECT_STREQ(_T("C:"), GetEnvironmentVariableAsString(_T("SystemDrive"))); |
| EXPECT_STREQ(_T("Windows_NT"), GetEnvironmentVariableAsString(_T("OS"))); |
| EXPECT_STREQ(_T(""), GetEnvironmentVariableAsString(_T("FOO"))); |
| } |
| |
| TEST(UtilsTest, IsWindowsInstalling_Normal) { |
| EXPECT_FALSE(IsWindowsInstalling()); |
| } |
| |
| TEST(UtilsTest, IsWindowsInstalling_Installing_Vista_InvalidValues) { |
| if (!vista_util::IsVistaOrLater()) { |
| return; |
| } |
| |
| RegKey::DeleteKey(kRegistryHiveOverrideRoot, true); |
| OverrideRegistryHives(kRegistryHiveOverrideRoot); |
| |
| EXPECT_SUCCEEDED(RegKey::SetValue( |
| _T("HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State"), |
| _T("ImageState"), |
| _T(""))); |
| EXPECT_FALSE(IsWindowsInstalling()); |
| |
| EXPECT_SUCCEEDED(RegKey::SetValue( |
| _T("HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State"), |
| _T("ImageState"), |
| _T("foo"))); |
| EXPECT_FALSE(IsWindowsInstalling()); |
| |
| EXPECT_SUCCEEDED(RegKey::SetValue( |
| _T("HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State"), |
| _T("ImageState"), |
| static_cast<DWORD>(1))); |
| ExpectAsserts expect_asserts; // RegKey asserts because value type is wrong. |
| EXPECT_FALSE(IsWindowsInstalling()); |
| |
| RestoreRegistryHives(); |
| EXPECT_SUCCEEDED(RegKey::DeleteKey(kRegistryHiveOverrideRoot, true)); |
| } |
| |
| TEST(UtilsTest, IsWindowsInstalling_Installing_Vista_ValidStates) { |
| if (!vista_util::IsVistaOrLater()) { |
| return; |
| } |
| |
| RegKey::DeleteKey(kRegistryHiveOverrideRoot, true); |
| OverrideRegistryHives(kRegistryHiveOverrideRoot); |
| |
| // These states return false in the original implementation. |
| EXPECT_SUCCEEDED(RegKey::SetValue( |
| _T("HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State"), |
| _T("ImageState"), |
| _T("IMAGE_STATE_COMPLETE"))); |
| EXPECT_FALSE(IsWindowsInstalling()); |
| |
| EXPECT_SUCCEEDED(RegKey::SetValue( |
| _T("HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State"), |
| _T("ImageState"), |
| _T("IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE"))); |
| EXPECT_FALSE(IsWindowsInstalling()); |
| |
| EXPECT_SUCCEEDED(RegKey::SetValue( |
| _T("HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State"), |
| _T("ImageState"), |
| _T("IMAGE_STATE_SPECIALIZE_RESEAL_TO_OOBE"))); |
| EXPECT_FALSE(IsWindowsInstalling()); |
| |
| // These states are specified in the original implementation. |
| EXPECT_SUCCEEDED(RegKey::SetValue( |
| _T("HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State"), |
| _T("ImageState"), |
| _T("IMAGE_STATE_UNDEPLOYABLE"))); |
| EXPECT_TRUE(IsWindowsInstalling()); |
| |
| EXPECT_SUCCEEDED(RegKey::SetValue( |
| _T("HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State"), |
| _T("ImageState"), |
| _T("IMAGE_STATE_GENERALIZE_RESEAL_TO_AUDIT"))); |
| EXPECT_TRUE(IsWindowsInstalling()); |
| |
| EXPECT_SUCCEEDED(RegKey::SetValue( |
| _T("HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State"), |
| _T("ImageState"), |
| _T("IMAGE_STATE_SPECIALIZE_RESEAL_TO_AUDIT"))); |
| EXPECT_TRUE(IsWindowsInstalling()); |
| |
| RestoreRegistryHives(); |
| EXPECT_SUCCEEDED(RegKey::DeleteKey(kRegistryHiveOverrideRoot, true)); |
| } |
| |
| TEST(UtilsTest, AddAllowedAce) { |
| CString test_file_path = ConcatenatePath( |
| app_util::GetCurrentModuleDirectory(), _T("TestAddAllowedAce.exe")); |
| EXPECT_SUCCEEDED(File::Remove(test_file_path)); |
| |
| EXPECT_SUCCEEDED(File::Copy( |
| ConcatenatePath(app_util::GetCurrentModuleDirectory(), |
| _T("GoogleUpdate.exe")), |
| test_file_path, |
| false)); |
| |
| CDacl dacl; |
| EXPECT_TRUE(AtlGetDacl(test_file_path, SE_FILE_OBJECT, &dacl)); |
| const int original_ace_count = dacl.GetAceCount(); |
| |
| EXPECT_SUCCEEDED(AddAllowedAce(test_file_path, |
| SE_FILE_OBJECT, |
| Sids::Dialup(), |
| FILE_GENERIC_READ, |
| 0)); |
| |
| dacl.SetEmpty(); |
| EXPECT_TRUE(AtlGetDacl(test_file_path, SE_FILE_OBJECT, &dacl)); |
| EXPECT_EQ(original_ace_count + 1, dacl.GetAceCount()); |
| |
| // Add the same access. No ACE is added. |
| EXPECT_SUCCEEDED(AddAllowedAce(test_file_path, |
| SE_FILE_OBJECT, |
| Sids::Dialup(), |
| FILE_GENERIC_READ, |
| 0)); |
| dacl.SetEmpty(); |
| EXPECT_TRUE(AtlGetDacl(test_file_path, SE_FILE_OBJECT, &dacl)); |
| EXPECT_EQ(original_ace_count + 1, dacl.GetAceCount()); |
| |
| // Add a subset of the existing access. No ACE is added. |
| EXPECT_EQ(FILE_READ_ATTRIBUTES, FILE_GENERIC_READ & FILE_READ_ATTRIBUTES); |
| EXPECT_SUCCEEDED(AddAllowedAce(test_file_path, |
| SE_FILE_OBJECT, |
| Sids::Dialup(), |
| FILE_READ_ATTRIBUTES, |
| 0)); |
| dacl.SetEmpty(); |
| EXPECT_TRUE(AtlGetDacl(test_file_path, SE_FILE_OBJECT, &dacl)); |
| EXPECT_EQ(original_ace_count + 1, dacl.GetAceCount()); |
| |
| // Add more access. An ACE is added. |
| EXPECT_SUCCEEDED(AddAllowedAce(test_file_path, |
| SE_FILE_OBJECT, |
| Sids::Dialup(), |
| FILE_ALL_ACCESS, |
| 0)); |
| dacl.SetEmpty(); |
| EXPECT_TRUE(AtlGetDacl(test_file_path, SE_FILE_OBJECT, &dacl)); |
| EXPECT_EQ(original_ace_count + 2, dacl.GetAceCount()); |
| |
| // TODO(omaha): An assert occurs because the ACE flags are being used on a |
| // file object. Add a new test to use a registry key. |
| ExpectAsserts expect_asserts; |
| |
| // Different ACE flags. An ACE is added. |
| const BYTE kTestAce = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE; |
| const BYTE kTestAceSubset = CONTAINER_INHERIT_ACE; |
| EXPECT_SUCCEEDED(AddAllowedAce(test_file_path, |
| SE_FILE_OBJECT, |
| Sids::Dialup(), |
| FILE_ALL_ACCESS, |
| kTestAce)); |
| dacl.SetEmpty(); |
| EXPECT_TRUE(AtlGetDacl(test_file_path, SE_FILE_OBJECT, &dacl)); |
| EXPECT_EQ(original_ace_count + 3, dacl.GetAceCount()); |
| |
| // Subset of existing ACE flags. An ACE is added because flags must be exact. |
| EXPECT_SUCCEEDED(AddAllowedAce(test_file_path, |
| SE_FILE_OBJECT, |
| Sids::Dialup(), |
| FILE_ALL_ACCESS, |
| kTestAceSubset)); |
| dacl.SetEmpty(); |
| EXPECT_TRUE(AtlGetDacl(test_file_path, SE_FILE_OBJECT, &dacl)); |
| EXPECT_EQ(original_ace_count + 4, dacl.GetAceCount()); |
| |
| // Same flags. An ACE should not be added because all values match. |
| // TODO(omaha): This does not work, possibly because the object is a file. |
| // Try the test using a registry key. |
| EXPECT_SUCCEEDED(AddAllowedAce(test_file_path, |
| SE_FILE_OBJECT, |
| Sids::Dialup(), |
| FILE_ALL_ACCESS, |
| kTestAceSubset)); |
| dacl.SetEmpty(); |
| EXPECT_TRUE(AtlGetDacl(test_file_path, SE_FILE_OBJECT, &dacl)); |
| EXPECT_EQ(original_ace_count + 5, dacl.GetAceCount()); |
| |
| EXPECT_SUCCEEDED(File::Remove(test_file_path)); |
| } |
| |
| TEST(UtilsTest, CreateForegroundParentWindowForUAC) { |
| CWindow foreground_parent; |
| foreground_parent.Attach(CreateForegroundParentWindowForUAC()); |
| EXPECT_TRUE(foreground_parent.IsWindow()); |
| EXPECT_TRUE(foreground_parent.IsWindowVisible()); |
| |
| CRect foreground_rect; |
| EXPECT_TRUE(foreground_parent.GetWindowRect(&foreground_rect)); |
| EXPECT_EQ(0, foreground_rect.Width()); |
| EXPECT_EQ(0, foreground_rect.Height()); |
| |
| EXPECT_TRUE((WS_POPUP | WS_VISIBLE) & foreground_parent.GetStyle()); |
| EXPECT_TRUE(WS_EX_TOOLWINDOW & foreground_parent.GetExStyle()); |
| |
| EXPECT_TRUE(foreground_parent.DestroyWindow()); |
| } |
| |
| } // namespace omaha |
| |