// Copyright (c) 2012 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.

// =============================================================================
// PLEASE READ
//
// In general, you should not be adding stuff to this file.
//
// - If your thing is only used in one place, just put it in a reasonable
//   location in or near that one place. It's nice you want people to be able
//   to re-use your function, but realistically, if it hasn't been necessary
//   before after so many years of development, it's probably not going to be
//   used in other places in the future unless you know of them now.
//
// - If your thing is used by multiple callers and is UI-related, it should
//   probably be in app/win/ instead. Try to put it in the most specific file
//   possible (avoiding the *_util files when practical).
//
// =============================================================================

#ifndef BASE_WIN_WIN_UTIL_H_
#define BASE_WIN_WIN_UTIL_H_

#include <stdint.h>
#include "base/win/windows_types.h"

#include <string>
#include <vector>

#include "base/strings/string16.h"

struct IPropertyStore;
struct _tagpropertykey;
typedef _tagpropertykey PROPERTYKEY;

namespace base {
namespace win {

inline uint32_t HandleToUint32(HANDLE h) {
  // Cast through uintptr_t and then unsigned int to make the truncation to
  // 32 bits explicit. Handles are size of-pointer but are always 32-bit values.
  // https://msdn.microsoft.com/en-us/library/aa384203(VS.85).aspx says:
  // 64-bit versions of Windows use 32-bit handles for interoperability.
  return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(h));
}

inline HANDLE Uint32ToHandle(uint32_t h) {
  return reinterpret_cast<HANDLE>(
      static_cast<uintptr_t>(static_cast<int32_t>(h)));
}

// Returns the string representing the current user sid.
bool GetUserSidString(std::wstring* user_sid);

// Returns false if user account control (UAC) has been disabled with the
// EnableLUA registry flag. Returns true if user account control is enabled.
// NOTE: The EnableLUA registry flag, which is ignored on Windows XP
// machines, might still exist and be set to 0 (UAC disabled), in which case
// this function will return false. You should therefore check this flag only
// if the OS is Vista or later.
bool UserAccountControlIsEnabled();

// Sets the boolean value for a given key in given IPropertyStore.
bool SetBooleanValueForPropertyStore(IPropertyStore* property_store,
                                     const PROPERTYKEY& property_key,
                                     bool property_bool_value);

// Sets the string value for a given key in given IPropertyStore.
bool SetStringValueForPropertyStore(IPropertyStore* property_store,
                                    const PROPERTYKEY& property_key,
                                    const wchar_t* property_string_value);

// Sets the CLSID value for a given key in a given IPropertyStore.
bool SetClsidForPropertyStore(IPropertyStore* property_store,
                              const PROPERTYKEY& property_key,
                              const CLSID& property_clsid_value);

// Sets the application id in given IPropertyStore. The function is intended
// for tagging application/chromium shortcut, browser window and jump list for
// Win7.
bool SetAppIdForPropertyStore(IPropertyStore* property_store,
                              const wchar_t* app_id);

// Adds the specified |command| using the specified |name| to the AutoRun key.
// |root_key| could be HKCU or HKLM or the root of any user hive.
bool AddCommandToAutoRun(HKEY root_key,
                         const string16& name,
                         const string16& command);
// Removes the command specified by |name| from the AutoRun key. |root_key|
// could be HKCU or HKLM or the root of any user hive.
bool RemoveCommandFromAutoRun(HKEY root_key, const string16& name);

// Reads the command specified by |name| from the AutoRun key. |root_key|
// could be HKCU or HKLM or the root of any user hive. Used for unit-tests.
bool ReadCommandFromAutoRun(HKEY root_key,
                            const string16& name,
                            string16* command);

// Sets whether to crash the process during exit. This is inspected by DLLMain
// and used to intercept unexpected terminations of the process (via calls to
// exit(), abort(), _exit(), ExitProcess()) and convert them into crashes.
// Note that not all mechanisms for terminating the process are covered by
// this. In particular, TerminateProcess() is not caught.
void SetShouldCrashOnProcessDetach(bool crash);
bool ShouldCrashOnProcessDetach();

// Adjusts the abort behavior so that crash reports can be generated when the
// process is aborted.
void SetAbortBehaviorForCrashReporting();

// Get the size of a struct up to and including the specified member.
// This is necessary to set compatible struct sizes for different versions
// of certain Windows APIs (e.g. SystemParametersInfo).
#define SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(struct_name, member) \
  offsetof(struct_name, member) +                                     \
      (sizeof static_cast<struct_name*>(NULL)->member)

// Used by tests to mock any wanted state. Call with |state| set to true to
// simulate being in a domain and false otherwise.
void SetDomainStateForTesting(bool state);

// Returns true if the current process can make USER32 or GDI32 calls such as
// CreateWindow and CreateDC. Windows 8 and above allow the kernel component
// of these calls to be disabled which can cause undefined behaviour such as
// crashes. This function can be used to guard areas of code using these calls
// and provide a fallback path if necessary.
bool IsUser32AndGdi32Available();

// Takes a snapshot of the modules loaded in the |process|. The returned
// HMODULEs are not add-ref'd, so they should not be closed and may be
// invalidated at any time (should a module be unloaded). |process| requires
// the PROCESS_QUERY_INFORMATION and PROCESS_VM_READ permissions.
bool GetLoadedModulesSnapshot(HANDLE process, std::vector<HMODULE>* snapshot);

// Adds or removes the MICROSOFT_TABLETPENSERVICE_PROPERTY property with the
// TABLET_DISABLE_FLICKS & TABLET_DISABLE_FLICKFALLBACKKEYS flags in order to
// disable pen flick gestures for the given HWND.
void EnableFlicks(HWND hwnd);
void DisableFlicks(HWND hwnd);

// Returns true if the process is per monitor DPI aware.
bool IsProcessPerMonitorDpiAware();

// Enable high-DPI support for the current process.
void EnableHighDPISupport();

}  // namespace win
}  // namespace base

#endif  // BASE_WIN_WIN_UTIL_H_
