// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <shlobj.h>
#include <shobjidl.h>

#include "content/browser/safe_util_win.h"

#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/scoped_comptr.h"
#include "ui/base/win/shell.h"
#include "url/gurl.h"

namespace content {
namespace {

// 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) {
  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

HRESULT AVScanFile(const base::FilePath& full_path,
                   const std::string& source_url,
                   const GUID& client_guid) {
  base::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 (!IsEqualGUID(client_guid, GUID_NULL)) {
    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;

  // Note: SetSource looks like it needs to be called, even if empty.
  // Docs say it is optional, but it appears not calling it at all sets
  // a zone that is too restrictive.
  hr = attachment_services->SetSource(base::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();
}

}  // namespace content
