/*
 * IQueryAssociations object and helper functions
 *
 * Copyright 2002 Jon Griffiths
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */
#include <stdarg.h>

#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "winreg.h"
#include "objbase.h"
#include "shlguid.h"
#include "shlwapi.h"
#include "shobjidl.h"
#include "shell32_main.h"
#include "ver.h"
#include "wine/unicode.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(shell);

/**************************************************************************
 *  IQueryAssociations
 *
 * DESCRIPTION
 *  This object provides a layer of abstraction over the system registry in
 *  order to simplify the process of parsing associations between files.
 *  Associations in this context means the registry entries that link (for
 *  example) the extension of a file with its description, list of
 *  applications to open the file with, and actions that can be performed on it
 *  (the shell displays such information in the context menu of explorer
 *  when you right-click on a file).
 *
 * HELPERS
 * You can use this object transparently by calling the helper functions
 * AssocQueryKeyA(), AssocQueryStringA() and AssocQueryStringByKeyA(). These
 * create an IQueryAssociations object, perform the requested actions
 * and then dispose of the object. Alternatively, you can create an instance
 * of the object using AssocCreate() and call the following methods on it:
 *
 * METHODS
 */

typedef struct
{
  IQueryAssociations IQueryAssociations_iface;
  LONG ref;
  HKEY hkeySource;
  HKEY hkeyProgID;
} IQueryAssociationsImpl;

typedef struct
{
  IApplicationAssociationRegistration IApplicationAssociationRegistration_iface;
  LONG ref;
} IApplicationAssociationRegistrationImpl;


static inline IQueryAssociationsImpl *impl_from_IQueryAssociations(IQueryAssociations *iface)
{
  return CONTAINING_RECORD(iface, IQueryAssociationsImpl, IQueryAssociations_iface);
}

struct enumassochandlers
{
    IEnumAssocHandlers IEnumAssocHandlers_iface;
    LONG ref;
};

static inline struct enumassochandlers *impl_from_IEnumAssocHandlers(IEnumAssocHandlers *iface)
{
  return CONTAINING_RECORD(iface, struct enumassochandlers, IEnumAssocHandlers_iface);
}

static HRESULT ASSOC_GetValue(HKEY hkey, const WCHAR *name, void **data, DWORD *data_size);

/**************************************************************************
 *  IQueryAssociations_QueryInterface
 *
 * See IUnknown_QueryInterface.
 */
static HRESULT WINAPI IQueryAssociations_fnQueryInterface(
  IQueryAssociations* iface,
  REFIID riid,
  LPVOID *ppvObj)
{
  IQueryAssociationsImpl *This = impl_from_IQueryAssociations(iface);

  TRACE("(%p,%s,%p)\n",This, debugstr_guid(riid), ppvObj);

  if (ppvObj == NULL)
      return E_POINTER;

  *ppvObj = NULL;

  if (IsEqualIID(riid, &IID_IUnknown) ||
      IsEqualIID(riid, &IID_IQueryAssociations))
  {
    *ppvObj = &This->IQueryAssociations_iface;

    IQueryAssociations_AddRef((IQueryAssociations*)*ppvObj);
    TRACE("Returning IQueryAssociations (%p)\n", *ppvObj);
    return S_OK;
  }
  TRACE("Returning E_NOINTERFACE\n");
  return E_NOINTERFACE;
}

/**************************************************************************
 *  IQueryAssociations_AddRef
 *
 * See IUnknown_AddRef.
 */
static ULONG WINAPI IQueryAssociations_fnAddRef(IQueryAssociations *iface)
{
  IQueryAssociationsImpl *This = impl_from_IQueryAssociations(iface);
  ULONG refCount = InterlockedIncrement(&This->ref);

  TRACE("(%p)->(ref before=%u)\n",This, refCount - 1);

  return refCount;
}

/**************************************************************************
 *  IQueryAssociations_Release
 *
 * See IUnknown_Release.
 */
static ULONG WINAPI IQueryAssociations_fnRelease(IQueryAssociations *iface)
{
  IQueryAssociationsImpl *This = impl_from_IQueryAssociations(iface);
  ULONG refCount = InterlockedDecrement(&This->ref);

  TRACE("(%p)->(ref before=%u)\n",This, refCount + 1);

  if (!refCount)
  {
    TRACE("Destroying IQueryAssociations (%p)\n", This);
    RegCloseKey(This->hkeySource);
    RegCloseKey(This->hkeyProgID);
    SHFree(This);
  }

  return refCount;
}

/**************************************************************************
 *  IQueryAssociations_Init
 *
 * Initialise an IQueryAssociations object.
 *
 * PARAMS
 *  iface      [I] IQueryAssociations interface to initialise
 *  cfFlags    [I] ASSOCF_ flags from "shlwapi.h"
 *  pszAssoc   [I] String for the root key name, or NULL if hkeyProgid is given
 *  hkeyProgid [I] Handle for the root key, or NULL if pszAssoc is given
 *  hWnd       [I] Reserved, must be NULL.
 *
 * RETURNS
 *  Success: S_OK. iface is initialised with the parameters given.
 *  Failure: An HRESULT error code indicating the error.
 */
static HRESULT WINAPI IQueryAssociations_fnInit(
  IQueryAssociations *iface,
  ASSOCF cfFlags,
  LPCWSTR pszAssoc,
  HKEY hkeyProgid,
  HWND hWnd)
{
    static const WCHAR szProgID[] = {'P','r','o','g','I','D',0};
    IQueryAssociationsImpl *This = impl_from_IQueryAssociations(iface);
    LONG ret;

    TRACE("(%p)->(%d,%s,%p,%p)\n", iface,
                                    cfFlags,
                                    debugstr_w(pszAssoc),
                                    hkeyProgid,
                                    hWnd);
    if (hWnd != NULL)
        FIXME("hwnd != NULL not supported\n");
    if (cfFlags != 0)
	FIXME("unsupported flags: %x\n", cfFlags);

    RegCloseKey(This->hkeySource);
    if (This->hkeySource != This->hkeyProgID)
        RegCloseKey(This->hkeyProgID);
    This->hkeySource = This->hkeyProgID = NULL;

    /* If the process of initializing hkeyProgID fails, just return S_OK. That's what Windows does. */
    if (pszAssoc != NULL)
    {
        WCHAR *progId;
        HRESULT hr;

        ret = RegOpenKeyExW(HKEY_CLASSES_ROOT,
                            pszAssoc,
                            0,
                            KEY_READ,
                            &This->hkeySource);
        if (ret)
            return S_OK;
        /* if this is a progid */
        if (*pszAssoc != '.' && *pszAssoc != '{')
        {
            This->hkeyProgID = This->hkeySource;
            return S_OK;
        }

        /* if it's not a progid, it's a file extension or clsid */
        if (*pszAssoc == '.')
        {
            /* for a file extension, the progid is the default value */
            hr = ASSOC_GetValue(This->hkeySource, NULL, (void**)&progId, NULL);
            if (FAILED(hr))
                return S_OK;
        }
        else /* if (*pszAssoc == '{') */
        {
            HKEY progIdKey;
            /* for a clsid, the progid is the default value of the ProgID subkey */
            ret = RegOpenKeyExW(This->hkeySource,
                                szProgID,
                                0,
                                KEY_READ,
                                &progIdKey);
            if (ret != ERROR_SUCCESS)
                return S_OK;
            hr = ASSOC_GetValue(progIdKey, NULL, (void**)&progId, NULL);
            if (FAILED(hr))
                return S_OK;
            RegCloseKey(progIdKey);
        }

        /* open the actual progid key, the one with the shell subkey */
        ret = RegOpenKeyExW(HKEY_CLASSES_ROOT,
                            progId,
                            0,
                            KEY_READ,
                            &This->hkeyProgID);
        HeapFree(GetProcessHeap(), 0, progId);

        return S_OK;
    }
    else if (hkeyProgid != NULL)
    {
        /* reopen the key so we don't end up closing a key owned by the caller */
        RegOpenKeyExW(hkeyProgid, NULL, 0, KEY_READ, &This->hkeyProgID);
        This->hkeySource = This->hkeyProgID;
        return S_OK;
    }
    else
        return E_INVALIDARG;
}

static HRESULT ASSOC_GetValue(HKEY hkey, const WCHAR *name, void **data, DWORD *data_size)
{
  DWORD size;
  LONG ret;

  ret = RegQueryValueExW(hkey, name, 0, NULL, NULL, &size);
  if (ret != ERROR_SUCCESS)
    return HRESULT_FROM_WIN32(ret);
  if (!size)
    return E_FAIL;
  *data = HeapAlloc(GetProcessHeap(), 0, size);
  if (!*data)
    return E_OUTOFMEMORY;
  ret = RegQueryValueExW(hkey, name, 0, NULL, (LPBYTE)*data, &size);
  if (ret != ERROR_SUCCESS)
  {
    HeapFree(GetProcessHeap(), 0, *data);
    return HRESULT_FROM_WIN32(ret);
  }
  if(data_size)
      *data_size = size;
  return S_OK;
}

static HRESULT ASSOC_GetCommand(IQueryAssociationsImpl *This, const WCHAR *extra, WCHAR **command)
{
  HKEY hkeyCommand;
  HKEY hkeyShell;
  HKEY hkeyVerb;
  HRESULT hr;
  LONG ret;
  WCHAR *extra_from_reg = NULL;
  WCHAR *filetype;
  static const WCHAR commandW[] = { 'c','o','m','m','a','n','d',0 };
  static const WCHAR shellW[] = { 's','h','e','l','l',0 };

  /* When looking for file extension it's possible to have a default value
     that points to another key that contains 'shell/<verb>/command' subtree. */
  hr = ASSOC_GetValue(This->hkeySource, NULL, (void**)&filetype, NULL);
  if (hr == S_OK)
  {
      HKEY hkeyFile;

      ret = RegOpenKeyExW(HKEY_CLASSES_ROOT, filetype, 0, KEY_READ, &hkeyFile);
      HeapFree(GetProcessHeap(), 0, filetype);

      if (ret == ERROR_SUCCESS)
      {
          ret = RegOpenKeyExW(hkeyFile, shellW, 0, KEY_READ, &hkeyShell);
          RegCloseKey(hkeyFile);
      }
      else
          ret = RegOpenKeyExW(This->hkeySource, shellW, 0, KEY_READ, &hkeyShell);
  }
  else
      ret = RegOpenKeyExW(This->hkeySource, shellW, 0, KEY_READ, &hkeyShell);

  if (ret) return HRESULT_FROM_WIN32(ret);

  if (!extra)
  {
      /* check for default verb */
      hr = ASSOC_GetValue(hkeyShell, NULL, (void**)&extra_from_reg, NULL);
      if (FAILED(hr))
      {
          /* no default verb, try first subkey */
          DWORD max_subkey_len;

          ret = RegQueryInfoKeyW(hkeyShell, NULL, NULL, NULL, NULL, &max_subkey_len, NULL, NULL, NULL, NULL, NULL, NULL);
          if (ret)
          {
              RegCloseKey(hkeyShell);
              return HRESULT_FROM_WIN32(ret);
          }

          max_subkey_len++;
          extra_from_reg = HeapAlloc(GetProcessHeap(), 0, max_subkey_len * sizeof(WCHAR));
          if (!extra_from_reg)
          {
              RegCloseKey(hkeyShell);
              return E_OUTOFMEMORY;
          }

          ret = RegEnumKeyExW(hkeyShell, 0, extra_from_reg, &max_subkey_len, NULL, NULL, NULL, NULL);
          if (ret)
          {
              HeapFree(GetProcessHeap(), 0, extra_from_reg);
              RegCloseKey(hkeyShell);
              return HRESULT_FROM_WIN32(ret);
          }
      }
      extra = extra_from_reg;
  }

  /* open verb subkey */
  ret = RegOpenKeyExW(hkeyShell, extra, 0, KEY_READ, &hkeyVerb);
  HeapFree(GetProcessHeap(), 0, extra_from_reg);
  RegCloseKey(hkeyShell);
  if (ret) return HRESULT_FROM_WIN32(ret);

  /* open command subkey */
  ret = RegOpenKeyExW(hkeyVerb, commandW, 0, KEY_READ, &hkeyCommand);
  RegCloseKey(hkeyVerb);
  if (ret) return HRESULT_FROM_WIN32(ret);

  hr = ASSOC_GetValue(hkeyCommand, NULL, (void**)command, NULL);
  RegCloseKey(hkeyCommand);
  return hr;
}

static HRESULT ASSOC_GetExecutable(IQueryAssociationsImpl *This,
                                   LPCWSTR pszExtra, LPWSTR path,
                                   DWORD pathlen, DWORD *len)
{
  WCHAR *pszCommand;
  WCHAR *pszStart;
  WCHAR *pszEnd;
  HRESULT hr;

  hr = ASSOC_GetCommand(This, pszExtra, &pszCommand);
  if (FAILED(hr))
    return hr;

  /* cleanup pszCommand */
  if (pszCommand[0] == '"')
  {
    pszStart = pszCommand + 1;
    pszEnd = strchrW(pszStart, '"');
    if (pszEnd)
      *pszEnd = 0;
    *len = SearchPathW(NULL, pszStart, NULL, pathlen, path, NULL);
  }
  else
  {
    pszStart = pszCommand;
    for (pszEnd = pszStart; (pszEnd = strchrW(pszEnd, ' ')); pszEnd++)
    {
      WCHAR c = *pszEnd;
      *pszEnd = 0;
      if ((*len = SearchPathW(NULL, pszStart, NULL, pathlen, path, NULL)))
        break;
      *pszEnd = c;
    }
    if (!pszEnd)
      *len = SearchPathW(NULL, pszStart, NULL, pathlen, path, NULL);
  }

  HeapFree(GetProcessHeap(), 0, pszCommand);
  if (!*len)
    return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  return S_OK;
}

static HRESULT ASSOC_ReturnData(void *out, DWORD *outlen, const void *data,
                                DWORD datalen)
{
  if (out)
  {
    if (*outlen < datalen)
    {
      *outlen = datalen;
      return E_POINTER;
    }
    *outlen = datalen;
    memcpy(out, data, datalen);
    return S_OK;
  }
  else
  {
    *outlen = datalen;
    return S_FALSE;
  }
}

static HRESULT ASSOC_ReturnString(ASSOCF flags, LPWSTR out, DWORD *outlen, LPCWSTR data, DWORD datalen)
{
    HRESULT hr = S_OK;
    DWORD len;

    TRACE("flags=0x%08x, data=%s\n", flags, debugstr_w(data));

    if (!out)
    {
        *outlen = datalen;
        return S_FALSE;
    }

    if (*outlen < datalen)
    {
        if (flags & ASSOCF_NOTRUNCATE)
        {
            len = 0;
            if (*outlen > 0) out[0] = 0;
            hr = E_POINTER;
        }
        else
        {
            len = min(*outlen, datalen);
            hr = E_NOT_SUFFICIENT_BUFFER;
        }
        *outlen = datalen;
    }
    else
        len = datalen;

    if (len)
        memcpy(out, data, len*sizeof(WCHAR));

    return hr;
}

/**************************************************************************
 *  IQueryAssociations_GetString
 *
 * Get a file association string from the registry.
 *
 * PARAMS
 *  iface    [I]   IQueryAssociations interface to query
 *  cfFlags  [I]   ASSOCF_ flags from "shlwapi.h"
 *  str      [I]   Type of string to get (ASSOCSTR enum from "shlwapi.h")
 *  pszExtra [I]   Extra information about the string location
 *  pszOut   [O]   Destination for the association string
 *  pcchOut  [I/O] Length of pszOut
 *
 * RETURNS
 *  Success: S_OK. pszOut contains the string, pcchOut contains its length.
 *  Failure: An HRESULT error code indicating the error.
 */
static HRESULT WINAPI IQueryAssociations_fnGetString(
  IQueryAssociations *iface,
  ASSOCF flags,
  ASSOCSTR str,
  LPCWSTR pszExtra,
  LPWSTR pszOut,
  DWORD *pcchOut)
{
  IQueryAssociationsImpl *This = impl_from_IQueryAssociations(iface);
  const ASSOCF unimplemented_flags = ~ASSOCF_NOTRUNCATE;
  DWORD len = 0;
  HRESULT hr;
  WCHAR path[MAX_PATH];

  TRACE("(%p)->(0x%08x, %u, %s, %p, %p)\n", This, flags, str, debugstr_w(pszExtra), pszOut, pcchOut);

  if (flags & unimplemented_flags)
    FIXME("%08x: unimplemented flags\n", flags & unimplemented_flags);

  if (!pcchOut)
    return E_UNEXPECTED;

  if (!This->hkeySource && !This->hkeyProgID)
    return HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION);

  switch (str)
  {
    case ASSOCSTR_COMMAND:
    {
      WCHAR *command;
      hr = ASSOC_GetCommand(This, pszExtra, &command);
      if (SUCCEEDED(hr))
      {
        hr = ASSOC_ReturnString(flags, pszOut, pcchOut, command, strlenW(command) + 1);
        HeapFree(GetProcessHeap(), 0, command);
      }
      return hr;
    }

    case ASSOCSTR_EXECUTABLE:
    {
      hr = ASSOC_GetExecutable(This, pszExtra, path, MAX_PATH, &len);
      if (FAILED(hr))
        return hr;
      len++;
      return ASSOC_ReturnString(flags, pszOut, pcchOut, path, len);
    }

    case ASSOCSTR_FRIENDLYDOCNAME:
    {
      WCHAR *docName;

      hr = ASSOC_GetValue(This->hkeyProgID, NULL, (void**)&docName, NULL);
      if (FAILED(hr)) {
          /* hKeyProgID is NULL or there is no default value, so fail */
          return HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION);
      }
      hr = ASSOC_ReturnString(flags, pszOut, pcchOut, docName, strlenW(docName) + 1);
      HeapFree(GetProcessHeap(), 0, docName);
      return hr;
    }

    case ASSOCSTR_FRIENDLYAPPNAME:
    {
      PVOID verinfoW = NULL;
      DWORD size, retval = 0;
      UINT flen;
      WCHAR *bufW;
      static const WCHAR translationW[] = {
        '\\','V','a','r','F','i','l','e','I','n','f','o',
        '\\','T','r','a','n','s','l','a','t','i','o','n',0
      };
      static const WCHAR fileDescFmtW[] = {
        '\\','S','t','r','i','n','g','F','i','l','e','I','n','f','o',
        '\\','%','0','4','x','%','0','4','x',
        '\\','F','i','l','e','D','e','s','c','r','i','p','t','i','o','n',0
      };
      WCHAR fileDescW[41];

      hr = ASSOC_GetExecutable(This, pszExtra, path, MAX_PATH, &len);
      if (FAILED(hr))
        return hr;

      retval = GetFileVersionInfoSizeW(path, &size);
      if (!retval)
        goto get_friendly_name_fail;
      verinfoW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, retval);
      if (!verinfoW)
        return E_OUTOFMEMORY;
      if (!GetFileVersionInfoW(path, 0, retval, verinfoW))
        goto get_friendly_name_fail;
      if (VerQueryValueW(verinfoW, translationW, (LPVOID *)&bufW, &flen))
      {
        UINT i;
        DWORD *langCodeDesc = (DWORD *)bufW;
        for (i = 0; i < flen / sizeof(DWORD); i++)
        {
          sprintfW(fileDescW, fileDescFmtW, LOWORD(langCodeDesc[i]),
                   HIWORD(langCodeDesc[i]));
          if (VerQueryValueW(verinfoW, fileDescW, (LPVOID *)&bufW, &flen))
          {
            /* Does strlenW(bufW) == 0 mean we use the filename? */
            len = strlenW(bufW) + 1;
            TRACE("found FileDescription: %s\n", debugstr_w(bufW));
            hr = ASSOC_ReturnString(flags, pszOut, pcchOut, bufW, len);
            HeapFree(GetProcessHeap(), 0, verinfoW);
            return hr;
          }
        }
      }
get_friendly_name_fail:
      PathRemoveExtensionW(path);
      PathStripPathW(path);
      TRACE("using filename: %s\n", debugstr_w(path));
      hr = ASSOC_ReturnString(flags, pszOut, pcchOut, path, strlenW(path) + 1);
      HeapFree(GetProcessHeap(), 0, verinfoW);
      return hr;
    }

    case ASSOCSTR_CONTENTTYPE:
    {
      static const WCHAR Content_TypeW[] = {'C','o','n','t','e','n','t',' ','T','y','p','e',0};
      WCHAR *contentType;
      DWORD ret;
      DWORD size;

      size = 0;
      ret = RegGetValueW(This->hkeySource, NULL, Content_TypeW, RRF_RT_REG_SZ, NULL, NULL, &size);
      if (ret != ERROR_SUCCESS)
        return HRESULT_FROM_WIN32(ret);
      contentType = HeapAlloc(GetProcessHeap(), 0, size);
      if (contentType != NULL)
      {
        ret = RegGetValueW(This->hkeySource, NULL, Content_TypeW, RRF_RT_REG_SZ, NULL, contentType, &size);
        if (ret == ERROR_SUCCESS)
          hr = ASSOC_ReturnString(flags, pszOut, pcchOut, contentType, strlenW(contentType) + 1);
        else
          hr = HRESULT_FROM_WIN32(ret);
        HeapFree(GetProcessHeap(), 0, contentType);
      }
      else
        hr = E_OUTOFMEMORY;
      return hr;
    }

    case ASSOCSTR_DEFAULTICON:
    {
      static const WCHAR DefaultIconW[] = {'D','e','f','a','u','l','t','I','c','o','n',0};
      static const WCHAR documentIcon[] = {'s','h','e','l','l','3','2','.','d','l','l',',','0',0};
      DWORD ret;
      DWORD size;

      size = 0;
      ret = RegGetValueW(This->hkeyProgID, DefaultIconW, NULL, RRF_RT_REG_SZ, NULL, NULL, &size);
      if (ret == ERROR_SUCCESS)
      {
        WCHAR *icon = HeapAlloc(GetProcessHeap(), 0, size);
        if (icon)
        {
          ret = RegGetValueW(This->hkeyProgID, DefaultIconW, NULL, RRF_RT_REG_SZ, NULL, icon, &size);
          if (ret == ERROR_SUCCESS)
            hr = ASSOC_ReturnString(flags, pszOut, pcchOut, icon, strlenW(icon) + 1);
          else
            hr = HRESULT_FROM_WIN32(ret);
          HeapFree(GetProcessHeap(), 0, icon);
        }
        else
          hr = E_OUTOFMEMORY;
      } else {
          /* there is no DefaultIcon subkey or hkeyProgID is NULL, so return the default document icon */
          if (This->hkeyProgID == NULL)
              hr = ASSOC_ReturnString(flags, pszOut, pcchOut, documentIcon, strlenW(documentIcon) + 1);
          else
              return HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION);
      }
      return hr;
    }
    case ASSOCSTR_SHELLEXTENSION:
    {
        static const WCHAR shellexW[] = {'S','h','e','l','l','E','x','\\',0};
        WCHAR keypath[sizeof(shellexW) / sizeof(shellexW[0]) + 39], guid[39];
        CLSID clsid;
        HKEY hkey;
        DWORD size;
        LONG ret;

        hr = CLSIDFromString(pszExtra, &clsid);
        if (FAILED(hr)) return hr;

        strcpyW(keypath, shellexW);
        strcatW(keypath, pszExtra);
        ret = RegOpenKeyExW(This->hkeySource, keypath, 0, KEY_READ, &hkey);
        if (ret) return HRESULT_FROM_WIN32(ret);

        size = sizeof(guid);
        ret = RegGetValueW(hkey, NULL, NULL, RRF_RT_REG_SZ, NULL, guid, &size);
        RegCloseKey(hkey);
        if (ret) return HRESULT_FROM_WIN32(ret);

        return ASSOC_ReturnString(flags, pszOut, pcchOut, guid, size / sizeof(WCHAR));
    }

    default:
      FIXME("assocstr %d unimplemented!\n", str);
      return E_NOTIMPL;
  }
}

/**************************************************************************
 *  IQueryAssociations_GetKey
 *
 * Get a file association key from the registry.
 *
 * PARAMS
 *  iface    [I] IQueryAssociations interface to query
 *  cfFlags  [I] ASSOCF_ flags from "shlwapi.h"
 *  assockey [I] Type of key to get (ASSOCKEY enum from "shlwapi.h")
 *  pszExtra [I] Extra information about the key location
 *  phkeyOut [O] Destination for the association key
 *
 * RETURNS
 *  Success: S_OK. phkeyOut contains a handle to the key.
 *  Failure: An HRESULT error code indicating the error.
 */
static HRESULT WINAPI IQueryAssociations_fnGetKey(
  IQueryAssociations *iface,
  ASSOCF cfFlags,
  ASSOCKEY assockey,
  LPCWSTR pszExtra,
  HKEY *phkeyOut)
{
  IQueryAssociationsImpl *This = impl_from_IQueryAssociations(iface);

  FIXME("(%p,0x%8x,0x%8x,%s,%p)-stub!\n", This, cfFlags, assockey,
        debugstr_w(pszExtra), phkeyOut);
  return E_NOTIMPL;
}

/**************************************************************************
 *  IQueryAssociations_GetData
 *
 * Get the data for a file association key from the registry.
 *
 * PARAMS
 *  iface     [I]   IQueryAssociations interface to query
 *  cfFlags   [I]   ASSOCF_ flags from "shlwapi.h"
 *  assocdata [I]   Type of data to get (ASSOCDATA enum from "shlwapi.h")
 *  pszExtra  [I]   Extra information about the data location
 *  pvOut     [O]   Destination for the association key
 *  pcbOut    [I/O] Size of pvOut
 *
 * RETURNS
 *  Success: S_OK. pszOut contains the data, pcbOut contains its length.
 *  Failure: An HRESULT error code indicating the error.
 */
static HRESULT WINAPI IQueryAssociations_fnGetData(IQueryAssociations *iface,
        ASSOCF cfFlags, ASSOCDATA assocdata, LPCWSTR pszExtra, LPVOID pvOut,
        DWORD *pcbOut)
{
    static const WCHAR edit_flags[] = {'E','d','i','t','F','l','a','g','s',0};

    IQueryAssociationsImpl *This = impl_from_IQueryAssociations(iface);
    void *data = NULL;
    DWORD size;
    HRESULT hres;

    TRACE("(%p,0x%8x,0x%8x,%s,%p,%p)\n", This, cfFlags, assocdata,
            debugstr_w(pszExtra), pvOut, pcbOut);

    if(cfFlags)
        FIXME("Unsupported flags: %x\n", cfFlags);

    switch(assocdata) {
    case ASSOCDATA_EDITFLAGS:
        if(!This->hkeyProgID)
            return HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION);

        hres = ASSOC_GetValue(This->hkeyProgID, edit_flags, &data, &size);
        if(SUCCEEDED(hres) && pcbOut)
            hres = ASSOC_ReturnData(pvOut, pcbOut, data, size);
        HeapFree(GetProcessHeap(), 0, data);
        return hres;
    default:
        FIXME("Unsupported ASSOCDATA value: %d\n", assocdata);
        return E_NOTIMPL;
    }
}

/**************************************************************************
 *  IQueryAssociations_GetEnum
 *
 * Not yet implemented in native Win32.
 *
 * PARAMS
 *  iface     [I] IQueryAssociations interface to query
 *  cfFlags   [I] ASSOCF_ flags from "shlwapi.h"
 *  assocenum [I] Type of enum to get (ASSOCENUM enum from "shlwapi.h")
 *  pszExtra  [I] Extra information about the enum location
 *  riid      [I] REFIID to look for
 *  ppvOut    [O] Destination for the interface.
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: An HRESULT error code indicating the error.
 *
 * NOTES
 *  Presumably this function returns an enumerator object.
 */
static HRESULT WINAPI IQueryAssociations_fnGetEnum(
  IQueryAssociations *iface,
  ASSOCF cfFlags,
  ASSOCENUM assocenum,
  LPCWSTR pszExtra,
  REFIID riid,
  LPVOID *ppvOut)
{
  IQueryAssociationsImpl *This = impl_from_IQueryAssociations(iface);

  FIXME("(%p,0x%8x,0x%8x,%s,%s,%p)-stub!\n", This, cfFlags, assocenum,
        debugstr_w(pszExtra), debugstr_guid(riid), ppvOut);
  return E_NOTIMPL;
}

static const IQueryAssociationsVtbl IQueryAssociations_vtbl =
{
  IQueryAssociations_fnQueryInterface,
  IQueryAssociations_fnAddRef,
  IQueryAssociations_fnRelease,
  IQueryAssociations_fnInit,
  IQueryAssociations_fnGetString,
  IQueryAssociations_fnGetKey,
  IQueryAssociations_fnGetData,
  IQueryAssociations_fnGetEnum
};

/**************************************************************************
 * IApplicationAssociationRegistration implementation
 */
static inline IApplicationAssociationRegistrationImpl *impl_from_IApplicationAssociationRegistration(IApplicationAssociationRegistration *iface)
{
  return CONTAINING_RECORD(iface, IApplicationAssociationRegistrationImpl, IApplicationAssociationRegistration_iface);
}

static HRESULT WINAPI ApplicationAssociationRegistration_QueryInterface(
                        IApplicationAssociationRegistration* iface, REFIID riid, LPVOID *ppv)
{
    IApplicationAssociationRegistrationImpl *This = impl_from_IApplicationAssociationRegistration(iface);

    TRACE("(%p, %s, %p)\n",This, debugstr_guid(riid), ppv);

    if (ppv == NULL)
        return E_POINTER;

    if (IsEqualGUID(&IID_IUnknown, riid) ||
        IsEqualGUID(&IID_IApplicationAssociationRegistration, riid)) {
        *ppv = &This->IApplicationAssociationRegistration_iface;
        IUnknown_AddRef((IUnknown*)*ppv);
        TRACE("returning IApplicationAssociationRegistration: %p\n", *ppv);
        return S_OK;
    }

    *ppv = NULL;
    FIXME("(%p)->(%s %p) interface not supported\n", This, debugstr_guid(riid), ppv);
    return E_NOINTERFACE;
}

static ULONG WINAPI ApplicationAssociationRegistration_AddRef(IApplicationAssociationRegistration *iface)
{
    IApplicationAssociationRegistrationImpl *This = impl_from_IApplicationAssociationRegistration(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);
    return ref;
}

static ULONG WINAPI ApplicationAssociationRegistration_Release(IApplicationAssociationRegistration *iface)
{
    IApplicationAssociationRegistrationImpl *This = impl_from_IApplicationAssociationRegistration(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    if (!ref) {
        SHFree(This);
    }
    return ref;
}

static HRESULT WINAPI ApplicationAssociationRegistration_QueryCurrentDefault(IApplicationAssociationRegistration *iface, LPCWSTR query,
                                                                             ASSOCIATIONTYPE type, ASSOCIATIONLEVEL level, LPWSTR *association)
{
    IApplicationAssociationRegistrationImpl *This = impl_from_IApplicationAssociationRegistration(iface);
    static WCHAR urlassoc[] = {'U','r','l','A','s','s','o','c','i','a','t','i','o','n','s',0};
    static WCHAR mimeassoc[] = {'M','I','M','E','A','s','s','o','c','i','a','t','i','o','n','s',0};
    static WCHAR assocations[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
                                'W','i','n','d','o','w','s','\\','S','h','e','l','l','\\',
                                'A','s','s','o','c','i','a','t','i','o','n','s',0};
    static WCHAR slash[] = {'\\',0};
    static WCHAR choice[] = {'U','s','e','r','C','h','o','i','c','e',0};
    static WCHAR propid[] = {'P','r','o','g','i','d',0};
    WCHAR path[MAX_PATH] = {0};
    DWORD ret, keytype, size;
    HKEY hkey = NULL;
    HRESULT hr = HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION);

    TRACE("(%p)->(%s, %d, %d, %p)\n", This, debugstr_w(query), type, level, association);

    if(!association)
        return E_INVALIDARG;

    *association = NULL;

    if((type == AT_URLPROTOCOL || type == AT_FILEEXTENSION) && !query[0])
        return E_INVALIDARG;
    else if(type == AT_FILEEXTENSION && query[0] != '.')
        return E_INVALIDARG;

    if(type == AT_FILEEXTENSION)
    {
        ret = RegOpenKeyExW(HKEY_CLASSES_ROOT, query, 0, KEY_READ, &hkey);
        if(ret == ERROR_SUCCESS)
        {
            ret = RegGetValueW(hkey, NULL, NULL, RRF_RT_REG_SZ, &keytype, NULL, &size);
            if(ret == ERROR_SUCCESS)
            {
                *association = CoTaskMemAlloc(size);
                if(*association)
                {
                    ret = RegGetValueW(hkey, NULL, NULL, RRF_RT_REG_SZ, &keytype, *association, &size);
                    if(ret == ERROR_SUCCESS)
                        hr = S_OK;
                    else
                    {
                        CoTaskMemFree(*association);
                        *association = NULL;
                    }
                }
                else
                    hr = E_OUTOFMEMORY;
            }
        }
    }
    else
    {
        ret = RegOpenKeyExW(HKEY_CURRENT_USER, assocations, 0, KEY_READ, &hkey);
        if(ret == ERROR_SUCCESS)
        {
            if(type == AT_URLPROTOCOL)
                lstrcpyW(path, urlassoc);
            else if(type == AT_MIMETYPE)
                lstrcpyW(path, mimeassoc);
            else
            {
                WARN("Unsupported type (%d).\n", type);
                RegCloseKey(hkey);
                return hr;
            }

            lstrcatW(path, slash);
            lstrcatW(path, query);
            lstrcatW(path, slash);
            lstrcatW(path, choice);

            ret = RegGetValueW(hkey, path, propid, RRF_RT_REG_SZ, &keytype, NULL, &size);
            if(ret == ERROR_SUCCESS)
            {
                *association = CoTaskMemAlloc(size);
                if(*association)
                {
                    ret = RegGetValueW(hkey, path, propid, RRF_RT_REG_SZ, &keytype, *association, &size);
                    if(ret == ERROR_SUCCESS)
                        hr = S_OK;
                    else
                    {
                        CoTaskMemFree(*association);
                        *association = NULL;
                    }
                }
                else
                    hr = E_OUTOFMEMORY;
            }
        }
    }

    RegCloseKey(hkey);

    return hr;
}

static HRESULT WINAPI ApplicationAssociationRegistration_QueryAppIsDefault(IApplicationAssociationRegistration* This, LPCWSTR query,
                                                                           ASSOCIATIONTYPE type, ASSOCIATIONLEVEL level, LPCWSTR appname, BOOL *is_default)
{
    FIXME("(%p)->(%s, %d, %d, %s, %p)\n", This, debugstr_w(query), type, level, debugstr_w(appname), is_default);
    return E_NOTIMPL;
}

static HRESULT WINAPI ApplicationAssociationRegistration_QueryAppIsDefaultAll(IApplicationAssociationRegistration* This, ASSOCIATIONLEVEL level,
                                                                              LPCWSTR appname, BOOL *is_default)
{
    FIXME("(%p)->(%d, %s, %p)\n", This, level, debugstr_w(appname), is_default);
    return E_NOTIMPL;
}

static HRESULT WINAPI ApplicationAssociationRegistration_SetAppAsDefault(IApplicationAssociationRegistration* This, LPCWSTR appname,
                                                                         LPCWSTR set, ASSOCIATIONTYPE set_type)
{
    FIXME("(%p)->(%s, %s, %d)\n", This, debugstr_w(appname), debugstr_w(set), set_type);
    return E_NOTIMPL;
}

static HRESULT WINAPI ApplicationAssociationRegistration_SetAppAsDefaultAll(IApplicationAssociationRegistration* This, LPCWSTR appname)
{
    FIXME("(%p)->(%s)\n", This, debugstr_w(appname));
    return E_NOTIMPL;
}


static HRESULT WINAPI ApplicationAssociationRegistration_ClearUserAssociations(IApplicationAssociationRegistration* This)
{
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}


static const IApplicationAssociationRegistrationVtbl IApplicationAssociationRegistration_vtbl =
{
    ApplicationAssociationRegistration_QueryInterface,
    ApplicationAssociationRegistration_AddRef,
    ApplicationAssociationRegistration_Release,
    ApplicationAssociationRegistration_QueryCurrentDefault,
    ApplicationAssociationRegistration_QueryAppIsDefault,
    ApplicationAssociationRegistration_QueryAppIsDefaultAll,
    ApplicationAssociationRegistration_SetAppAsDefault,
    ApplicationAssociationRegistration_SetAppAsDefaultAll,
    ApplicationAssociationRegistration_ClearUserAssociations
};

/**************************************************************************
 *  IQueryAssociations_Constructor [internal]
 *
 * Construct a new IQueryAssociations object.
 */
HRESULT WINAPI QueryAssociations_Constructor(IUnknown *pUnkOuter, REFIID riid, LPVOID *ppOutput)
{
    IQueryAssociationsImpl* this;
    HRESULT ret;

    if (pUnkOuter) return CLASS_E_NOAGGREGATION;

    if (!(this = SHAlloc(sizeof(*this)))) return E_OUTOFMEMORY;
    this->IQueryAssociations_iface.lpVtbl = &IQueryAssociations_vtbl;
    this->ref = 0;
    this->hkeySource = 0;
    this->hkeyProgID = 0;
    if (FAILED(ret = IQueryAssociations_QueryInterface(&this->IQueryAssociations_iface, riid, ppOutput))) SHFree( this );
    TRACE("returning %p\n", *ppOutput);
    return ret;
}

/**************************************************************************
 * ApplicationAssociationRegistration_Constructor [internal]
 *
 * Construct a IApplicationAssociationRegistration object.
 */
HRESULT WINAPI ApplicationAssociationRegistration_Constructor(IUnknown *outer, REFIID riid, LPVOID *ppv)
{
    IApplicationAssociationRegistrationImpl *This;
    HRESULT hr;

    if (outer)
        return CLASS_E_NOAGGREGATION;

    if (!(This = SHAlloc(sizeof(*This))))
        return E_OUTOFMEMORY;

    This->IApplicationAssociationRegistration_iface.lpVtbl = &IApplicationAssociationRegistration_vtbl;
    This->ref = 0;

    hr = IApplicationAssociationRegistration_QueryInterface(&This->IApplicationAssociationRegistration_iface, riid, ppv);
    if (FAILED(hr))
        SHFree(This);

    TRACE("returning 0x%x with %p\n", hr, *ppv);
    return hr;
}

static HRESULT WINAPI enumassochandlers_QueryInterface(IEnumAssocHandlers *iface, REFIID riid, void **obj)
{
    struct enumassochandlers *This = impl_from_IEnumAssocHandlers(iface);

    TRACE("(%p %s %p)\n", This, debugstr_guid(riid), obj);

    if (IsEqualIID(riid, &IID_IEnumAssocHandlers) ||
        IsEqualIID(riid, &IID_IUnknown))
    {
        *obj = iface;
        IEnumAssocHandlers_AddRef(iface);
        return S_OK;
    }

    *obj = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI enumassochandlers_AddRef(IEnumAssocHandlers *iface)
{
    struct enumassochandlers *This = impl_from_IEnumAssocHandlers(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p)->(%u)\n", This, ref);
    return ref;
}

static ULONG WINAPI enumassochandlers_Release(IEnumAssocHandlers *iface)
{
    struct enumassochandlers *This = impl_from_IEnumAssocHandlers(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(%u)\n", This, ref);

    if (!ref)
        SHFree(This);

    return ref;
}

static HRESULT WINAPI enumassochandlers_Next(IEnumAssocHandlers *iface, ULONG count, IAssocHandler **handlers,
    ULONG *fetched)
{
    struct enumassochandlers *This = impl_from_IEnumAssocHandlers(iface);

    FIXME("(%p)->(%u %p %p): stub\n", This, count, handlers, fetched);

    return E_NOTIMPL;
}

static const IEnumAssocHandlersVtbl enumassochandlersvtbl = {
    enumassochandlers_QueryInterface,
    enumassochandlers_AddRef,
    enumassochandlers_Release,
    enumassochandlers_Next
};

/**************************************************************************
 * SHAssocEnumHandlers            [SHELL32.@]
 */
HRESULT WINAPI SHAssocEnumHandlers(const WCHAR *extra, ASSOC_FILTER filter, IEnumAssocHandlers **enumhandlers)
{
    struct enumassochandlers *enumassoc;

    FIXME("(%s %d %p): stub\n", debugstr_w(extra), filter, enumhandlers);

    *enumhandlers = NULL;

    enumassoc = SHAlloc(sizeof(*enumassoc));
    if (!enumassoc)
        return E_OUTOFMEMORY;

    enumassoc->IEnumAssocHandlers_iface.lpVtbl = &enumassochandlersvtbl;
    enumassoc->ref = 1;

    *enumhandlers = &enumassoc->IEnumAssocHandlers_iface;
    return S_OK;
}
