Chromium Code Reviews| Index: base/file_util_win.cc |
| diff --git a/base/file_util_win.cc b/base/file_util_win.cc |
| index 39317a3a932777a3a10f635ba9024f7a92a4746e..1541a8f8720e6538137f0864d7ba86a4e169bc9c 100644 |
| --- a/base/file_util_win.cc |
| +++ b/base/file_util_win.cc |
| @@ -24,6 +24,7 @@ |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/threading/thread_restrictions.h" |
| #include "base/time/time.h" |
| +#include "base/win/scoped_comptr.h" |
| #include "base/win/scoped_handle.h" |
| #include "base/win/windows_version.h" |
| @@ -72,6 +73,36 @@ bool ShellCopy(const FilePath& from_path, |
| return (SHFileOperation(&file_operation) == 0); |
| } |
| +// Sets the Zone Identifier on the file to "Internet" (3). Returns true if the |
| +// function succeeds, false otherwise. A failure is expected on system where |
| +// the Zone Identifier is not supported, like a machine with a FAT32 filesystem. |
| +// This function does not invoke Windows Attachment Execution Services. |
| +// |
| +// |full_path| is the path to the downloaded file. |
| +bool SetInternetZoneIdentifierDirectly(const base::FilePath& full_path) { |
|
Lei Zhang
2013/08/07 01:03:05
nit: no need for base:: instead namespace base.
Greg Billock
2013/08/07 17:00:56
Done.
|
| + const DWORD kShare = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; |
| + std::wstring path = full_path.value() + L":Zone.Identifier"; |
| + HANDLE file = CreateFile(path.c_str(), GENERIC_WRITE, kShare, NULL, |
| + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); |
| + if (INVALID_HANDLE_VALUE == file) |
| + return false; |
| + |
| + static const char kIdentifier[] = "[ZoneTransfer]\r\nZoneId=3\r\n"; |
| + // Don't include trailing null in data written. |
| + static const DWORD kIdentifierSize = arraysize(kIdentifier) - 1; |
| + DWORD written = 0; |
| + BOOL result = WriteFile(file, kIdentifier, kIdentifierSize, &written, NULL); |
| + BOOL flush_result = FlushFileBuffers(file); |
| + CloseHandle(file); |
| + |
| + if (!result || !flush_result || written != kIdentifierSize) { |
| + NOTREACHED(); |
| + return false; |
| + } |
| + |
| + return true; |
| +} |
| + |
| } // namespace |
| FilePath MakeAbsoluteFilePath(const FilePath& input) { |
| @@ -147,6 +178,44 @@ bool DeleteFileAfterReboot(const FilePath& path) { |
| MOVEFILE_REPLACE_EXISTING) != FALSE; |
| } |
| +HRESULT AVScanFile(const FilePath& full_path, |
| + const std::string& source_url, |
| + const GUID& client_guid) { |
| + win::ScopedComPtr<IAttachmentExecute> attachment_services; |
| + HRESULT hr = attachment_services.CreateInstance(CLSID_AttachmentServices); |
| + |
| + if (FAILED(hr)) { |
| + // The thread must have COM initialized. |
| + DCHECK_NE(CO_E_NOTINITIALIZED, hr); |
| + |
| + // We don't have Attachment Execution Services, it must be a pre-XP.SP2 |
| + // Windows installation, or the thread does not have COM initialized. Try to |
| + // set the zone information directly. Failure is not considered an error. |
| + SetInternetZoneIdentifierDirectly(full_path); |
| + return hr; |
| + } |
| + |
| + if (client_guid != GUID_NULL) { |
|
asanka
2013/08/07 16:42:36
IsEqualGUID(). Or take a const GUID* and check if
Greg Billock
2013/08/07 17:42:56
Done.
|
| + hr = attachment_services->SetClientGuid(client_guid); |
| + if (FAILED(hr)) |
| + return hr; |
| + } |
| + |
| + hr = attachment_services->SetLocalPath(full_path.value().c_str()); |
| + if (FAILED(hr)) |
| + return hr; |
| + |
| + if (!source_url.empty()) { |
| + hr = attachment_services->SetSource(UTF8ToWide(source_url).c_str()); |
| + if (FAILED(hr)) |
| + return hr; |
| + } |
| + |
| + // A failure in the Save() call below could result in the downloaded file |
| + // being deleted. |
| + return attachment_services->Save(); |
| +} |
| + |
| bool ReplaceFile(const FilePath& from_path, |
| const FilePath& to_path, |
| PlatformFileError* error) { |