15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <shlobj.h> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <shobjidl.h> 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/safe_util_win.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_comptr.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/win/shell.h" 177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets the Zone Identifier on the file to "Internet" (3). Returns true if the 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// function succeeds, false otherwise. A failure is expected on system where 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the Zone Identifier is not supported, like a machine with a FAT32 filesystem. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This function does not invoke Windows Attachment Execution Services. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |full_path| is the path to the downloaded file. 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SetInternetZoneIdentifierDirectly(const base::FilePath& full_path) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DWORD kShare = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring path = full_path.value() + L":Zone.Identifier"; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE file = CreateFile(path.c_str(), GENERIC_WRITE, kShare, NULL, 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (INVALID_HANDLE_VALUE == file) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kIdentifier[] = "[ZoneTransfer]\r\nZoneId=3\r\n"; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't include trailing null in data written. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const DWORD kIdentifierSize = arraysize(kIdentifier) - 1; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD written = 0; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BOOL result = WriteFile(file, kIdentifier, kIdentifierSize, &written, NULL); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BOOL flush_result = FlushFileBuffers(file); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseHandle(file); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result || !flush_result || written != kIdentifierSize) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 524311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch} // namespace 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 544311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen MurdochHRESULT AVScanFile(const base::FilePath& full_path, 554311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch const std::string& source_url, 564311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch const GUID& client_guid) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ScopedComPtr<IAttachmentExecute> attachment_services; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = attachment_services.CreateInstance(CLSID_AttachmentServices); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FAILED(hr)) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The thread must have COM initialized. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(CO_E_NOTINITIALIZED, hr); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't have Attachment Execution Services, it must be a pre-XP.SP2 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Windows installation, or the thread does not have COM initialized. Try to 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // set the zone information directly. Failure is not considered an error. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetInternetZoneIdentifierDirectly(full_path); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hr; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 714311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch if (!IsEqualGUID(client_guid, GUID_NULL)) { 724311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch hr = attachment_services->SetClientGuid(client_guid); 734311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch if (FAILED(hr)) 744311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch return hr; 754311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = attachment_services->SetLocalPath(full_path.value().c_str()); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FAILED(hr)) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hr; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 814311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch // Note: SetSource looks like it needs to be called, even if empty. 824311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch // Docs say it is optional, but it appears not calling it at all sets 834311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch // a zone that is too restrictive. 844311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch hr = attachment_services->SetSource(UTF8ToWide(source_url).c_str()); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FAILED(hr)) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hr; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A failure in the Save() call below could result in the downloaded file 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // being deleted. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return attachment_services->Save(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 94