summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/installer/setup/install.cc75
-rw-r--r--chrome/installer/setup/setup_constants.cc1
-rw-r--r--chrome/installer/setup/setup_constants.h1
-rw-r--r--chrome/installer/util/copy_tree_work_item.cc6
-rw-r--r--chrome/installer/util/copy_tree_work_item_unittest.cc79
-rw-r--r--chrome/installer/util/work_item.h1
6 files changed, 116 insertions, 47 deletions
diff --git a/chrome/installer/setup/install.cc b/chrome/installer/setup/install.cc
index e06f936..9cdd58d 100644
--- a/chrome/installer/setup/install.cc
+++ b/chrome/installer/setup/install.cc
@@ -187,54 +187,35 @@ bool installer::InstallNewVersion(const std::wstring& exe_path,
install_list->AddCreateDirWorkItem(temp_dir);
install_list->AddCreateDirWorkItem(install_path);
- // Browse for all the files in archive, add work items to copy them while
- // handling special cases of executables.
- LOG(INFO) << "Looking for Chrome installation files under " << src_path;
- std::wstring root_path(src_path);
- file_util::AppendToPath(&root_path, L"*");
- WIN32_FIND_DATA find_file_data;
- HANDLE file_handle = FindFirstFile(root_path.c_str(), &find_file_data);
- BOOL ret = TRUE;
- while (ret) {
- LOG(INFO) << "directory found: " << find_file_data.cFileName;
- // We do not want any directories starting with '.'
- if ((wcslen(find_file_data.cFileName) <= 0) ||
- (find_file_data.cFileName[0] == '.')) {
- LOG(INFO) << "Ignoring directory found: " << find_file_data.cFileName;
- } else if (_wcsicmp(find_file_data.cFileName,
- installer_util::kChromeExe) == 0) {
- // Special case of chrome.exe. Delete any new_chrome.exe if present
- // (we will create a new one if chrome.exe is in use) and then
- // copy chrome.exe.
- install_list->AddDeleteTreeWorkItem(
- AppendPath(install_path, installer::kChromeNewExe), std::wstring());
- install_list->AddCopyTreeWorkItem(
- AppendPath(src_path, installer_util::kChromeExe),
- AppendPath(install_path, installer_util::kChromeExe),
- temp_dir, WorkItem::RENAME_IF_IN_USE,
- AppendPath(install_path, installer::kChromeNewExe));
- } else if (_wcsicmp(find_file_data.cFileName,
- installer::kWowHelperExe) == 0) {
- // Special case of wow_helper.exe which is required only on 64 bit
- // systems. This exe runs only for a short time when Chrome starts so
- // it should not be locked most of the times and can be overwritten
- // directly.
- if (Is64bit()) {
- install_list->AddCopyTreeWorkItem(
- AppendPath(src_path, installer::kWowHelperExe),
- AppendPath(install_path, installer::kWowHelperExe),
- temp_dir, WorkItem::ALWAYS);
- }
- } else {
- // In all other cases just copy the file/directory to install location.
- install_list->AddCopyTreeWorkItem(
- AppendPath(src_path, find_file_data.cFileName),
- AppendPath(install_path, find_file_data.cFileName),
- temp_dir, WorkItem::ALWAYS); // Always overwrite.
- }
- ret = FindNextFile(file_handle, &find_file_data);
+ // Copy the version folder
+ install_list->AddCopyTreeWorkItem(
+ AppendPath(src_path, new_version.GetString()),
+ AppendPath(install_path, new_version.GetString()),
+ temp_dir, WorkItem::ALWAYS); // Always overwrite.
+
+ // Delete any new_chrome.exe if present (we will end up create a new one
+ // if required) and then copy chrome.exe
+ install_list->AddDeleteTreeWorkItem(
+ AppendPath(install_path, installer::kChromeNewExe), std::wstring());
+ install_list->AddCopyTreeWorkItem(
+ AppendPath(src_path, installer_util::kChromeExe),
+ AppendPath(install_path, installer_util::kChromeExe),
+ temp_dir, WorkItem::RENAME_IF_IN_USE,
+ AppendPath(install_path, installer::kChromeNewExe));
+
+ // Extra executable for 64 bit systems.
+ if (Is64bit()) {
+ install_list->AddCopyTreeWorkItem(
+ AppendPath(src_path, installer::kWowHelperExe),
+ AppendPath(install_path, installer::kWowHelperExe),
+ temp_dir, WorkItem::ALWAYS);
}
- FindClose(file_handle);
+
+ // Copy the default Dictionaries only if the folder doesnt exist already
+ install_list->AddCopyTreeWorkItem(
+ AppendPath(src_path, installer::kDictionaries),
+ AppendPath(install_path, installer::kDictionaries),
+ temp_dir, WorkItem::IF_NOT_PRESENT);
// Copy installer in install directory and
// add shortcut in Control Panel->Add/Remove Programs.
diff --git a/chrome/installer/setup/setup_constants.cc b/chrome/installer/setup/setup_constants.cc
index 3397836..ef58ddb 100644
--- a/chrome/installer/setup/setup_constants.cc
+++ b/chrome/installer/setup/setup_constants.cc
@@ -34,6 +34,7 @@ namespace installer {
const wchar_t kChromeOldExe[] = L"old_chrome.exe";
const wchar_t kChromeNewExe[] = L"new_chrome.exe";
const wchar_t kWowHelperExe[] = L"wow_helper.exe";
+const wchar_t kDictionaries[] = L"Dictionaries";
const wchar_t kChromeArchive[] = L"chrome.7z";
const wchar_t kChromePatchArchive[] = L"patch.7z";
const wchar_t kChromeCompressedArchive[] = L"chrome.packed.7z";
diff --git a/chrome/installer/setup/setup_constants.h b/chrome/installer/setup/setup_constants.h
index 7e4bc48..85f8f88 100644
--- a/chrome/installer/setup/setup_constants.h
+++ b/chrome/installer/setup/setup_constants.h
@@ -37,6 +37,7 @@ namespace installer {
extern const wchar_t kChromeOldExe[];
extern const wchar_t kChromeNewExe[];
extern const wchar_t kWowHelperExe[];
+extern const wchar_t kDictionaries[];
extern const wchar_t kChromeArchive[];
extern const wchar_t kChromePatchArchive[];
extern const wchar_t kChromeCompressedArchive[];
diff --git a/chrome/installer/util/copy_tree_work_item.cc b/chrome/installer/util/copy_tree_work_item.cc
index c6eaacd..f61d5c7 100644
--- a/chrome/installer/util/copy_tree_work_item.cc
+++ b/chrome/installer/util/copy_tree_work_item.cc
@@ -93,6 +93,12 @@ bool CopyTreeWorkItem::Do() {
}
}
+ // handle overwrite_option_ = IF_NOT_PRESENT case
+ if ((dest_exist) &&
+ (overwrite_option_ == WorkItem::IF_NOT_PRESENT)) {
+ return true;
+ }
+
// All other cases where we move dest if it exists, and copy the files
if (dest_exist) {
if (!GetBackupPath())
diff --git a/chrome/installer/util/copy_tree_work_item_unittest.cc b/chrome/installer/util/copy_tree_work_item_unittest.cc
index 40e4a95..da75a8c 100644
--- a/chrome/installer/util/copy_tree_work_item_unittest.cc
+++ b/chrome/installer/util/copy_tree_work_item_unittest.cc
@@ -500,6 +500,85 @@ TEST_F(CopyTreeWorkItemTest, RenameAndCopyTest) {
EXPECT_FALSE(file_util::PathExists(alternate_to));
}
+// Test overwrite option IF_NOT_PRESENT:
+// 1. If destination file/directory exist, the source should not be copied
+// 2. If destination file/directory do not exist, the source should be copied
+// in the destination folder after Do() and should be rolled back after
+// Rollback().
+TEST_F(CopyTreeWorkItemTest, IfNotPresentTest) {
+ // Create source file
+ std::wstring file_name_from(test_dir_);
+ file_util::AppendToPath(&file_name_from, L"File_From");
+ CreateTextFile(file_name_from, text_content_1);
+ ASSERT_TRUE(file_util::PathExists(file_name_from));
+
+ // Create an executable in destination path by copying ourself to it.
+ wchar_t exe_full_path_str[MAX_PATH];
+ ::GetModuleFileNameW(NULL, exe_full_path_str, MAX_PATH);
+ std::wstring exe_full_path(exe_full_path_str);
+ std::wstring dir_name_to(test_dir_);
+ file_util::AppendToPath(&dir_name_to, L"Copy_To_Subdir");
+ CreateDirectory(dir_name_to.c_str(), NULL);
+ ASSERT_TRUE(file_util::PathExists(dir_name_to));
+ std::wstring file_name_to(dir_name_to);
+ file_util::AppendToPath(&file_name_to, L"File_To");
+ file_util::CopyFile(exe_full_path, file_name_to);
+ ASSERT_TRUE(file_util::PathExists(file_name_to));
+
+ // Get the path of backup file
+ std::wstring backup_file(temp_dir_);
+ file_util::AppendToPath(&backup_file, L"File_To");
+
+ // test Do().
+ scoped_ptr<CopyTreeWorkItem> work_item(
+ WorkItem::CreateCopyTreeWorkItem(file_name_from, file_name_to,
+ temp_dir_, WorkItem::IF_NOT_PRESENT,
+ L""));
+ EXPECT_TRUE(work_item->Do());
+
+ // verify that the source, destination have not changed and backup path
+ // does not exist
+ EXPECT_TRUE(file_util::PathExists(file_name_from));
+ EXPECT_TRUE(file_util::PathExists(file_name_to));
+ EXPECT_EQ(0, ReadTextFile(file_name_from).compare(text_content_1));
+ EXPECT_TRUE(file_util::ContentsEqual(exe_full_path, file_name_to));
+ EXPECT_FALSE(file_util::PathExists(backup_file));
+
+ // test rollback()
+ work_item->Rollback();
+
+ // verify that the source, destination have not changed and backup path
+ // does not exist after rollback also
+ EXPECT_TRUE(file_util::PathExists(file_name_from));
+ EXPECT_TRUE(file_util::PathExists(file_name_to));
+ EXPECT_EQ(0, ReadTextFile(file_name_from).compare(text_content_1));
+ EXPECT_TRUE(file_util::ContentsEqual(exe_full_path, file_name_to));
+ EXPECT_FALSE(file_util::PathExists(backup_file));
+
+ // Now delete the destination and try copying the file again.
+ file_util::Delete(file_name_to, true);
+ work_item.reset(WorkItem::CreateCopyTreeWorkItem(
+ file_name_from, file_name_to, temp_dir_, WorkItem::IF_NOT_PRESENT, L""));
+ EXPECT_TRUE(work_item->Do());
+
+ // verify that the source, destination are the same and backup path
+ // does not exist
+ EXPECT_TRUE(file_util::PathExists(file_name_from));
+ EXPECT_TRUE(file_util::PathExists(file_name_to));
+ EXPECT_EQ(0, ReadTextFile(file_name_from).compare(text_content_1));
+ EXPECT_EQ(0, ReadTextFile(file_name_to).compare(text_content_1));
+ EXPECT_FALSE(file_util::PathExists(backup_file));
+
+ // test rollback()
+ work_item->Rollback();
+
+ // verify that the destination does not exist anymore
+ EXPECT_TRUE(file_util::PathExists(file_name_from));
+ EXPECT_FALSE(file_util::PathExists(file_name_to));
+ EXPECT_EQ(0, ReadTextFile(file_name_from).compare(text_content_1));
+ EXPECT_FALSE(file_util::PathExists(backup_file));
+}
+
// Copy one file without rollback. The existing one in destination is in use.
// Verify it is moved to backup location and stays there.
TEST_F(CopyTreeWorkItemTest, CopyFileInUseAndCleanup) {
diff --git a/chrome/installer/util/work_item.h b/chrome/installer/util/work_item.h
index c167cf3..1060857 100644
--- a/chrome/installer/util/work_item.h
+++ b/chrome/installer/util/work_item.h
@@ -53,6 +53,7 @@ class WorkItem {
ALWAYS, // Always overwrite regardless of what existed before.
NEVER, // Not used currently.
IF_DIFFERENT, // Overwrite if different. Currently only applies to file.
+ IF_NOT_PRESENT, // Copy only if file/directory do not exist already.
RENAME_IF_IN_USE // Copy to a new path instead of overwriting (only files).
};