/*
 *	pidl Handling
 *
 *	Copyright 1998	Juergen Schmied
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * NOTES
 *  a pidl == NULL means desktop and is legal
 *
 */

#include "config.h"
#include "wine/port.h"

#include <ctype.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "objbase.h"
#include "shlguid.h"
#include "winerror.h"
#include "winnls.h"
#include "undocshell.h"
#include "shell32_main.h"
#include "shellapi.h"
#include "shlwapi.h"

#include "pidl.h"
#include "debughlp.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(pidl);
WINE_DECLARE_DEBUG_CHANNEL(shell);

/* from comctl32.dll */
extern LPVOID WINAPI Alloc(INT);
extern BOOL WINAPI Free(LPVOID);

/*************************************************************************
 * ILGetDisplayNameEx		[SHELL32.186]
 *
 * Retrieves the display name of an ItemIDList
 *
 * PARAMS
 *  psf        [I]   Shell Folder to start with, if NULL the desktop is used
 *  pidl       [I]   ItemIDList relativ to the psf to get the display name for
 *  path       [O]   Filled in with the display name, assumed to be at least MAX_PATH long
 *  type       [I]   Type of display name to retrieve
 *                    0 = SHGDN_FORPARSING | SHGDN_FORADDRESSBAR uses always the desktop as root
 *                    1 = SHGDN_NORMAL relative to the root folder
 *                    2 = SHGDN_INFOLDER relative to the root folder, only the last name
 *
 * RETURNS
 *  True if the display name could be retrieved successfully, False otherwise
 */
BOOL WINAPI ILGetDisplayNameExA(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, LPSTR path, DWORD type)
{
	BOOL ret = FALSE;
	WCHAR wPath[MAX_PATH];

	TRACE("%p %p %p %ld\n", psf, pidl, path, type);

	if (!pidl || !path)
	  return FALSE;

	ret = ILGetDisplayNameExW(psf, pidl, wPath, type);
	WideCharToMultiByte(CP_ACP, 0, wPath, -1, path, MAX_PATH, NULL, NULL);
	TRACE("%p %p %s\n", psf, pidl, debugstr_a(path));

	return ret;
}

BOOL WINAPI ILGetDisplayNameExW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, LPWSTR path, DWORD type)
{
	LPSHELLFOLDER psfParent, lsf = psf;
	HRESULT ret = NO_ERROR;
	LPCITEMIDLIST pidllast;
	STRRET strret;
	DWORD flag;

	TRACE("%p %p %p %ld\n", psf, pidl, path, type);

	if (!pidl || !path)
	  return FALSE;

	if (!lsf)
	{
	  ret = SHGetDesktopFolder(&lsf);
	  if (FAILED(ret))
	    return FALSE;
	}

	if (type >= 0 && type <= 2)
	{
	  switch (type)
	  {
	    case ILGDN_FORPARSING:
	      flag = SHGDN_FORPARSING | SHGDN_FORADDRESSBAR;
	      break;
	    case ILGDN_NORMAL:
	      flag = SHGDN_NORMAL;
	      break;
	    case ILGDN_INFOLDER:
	      flag = SHGDN_INFOLDER;
	      break;
	    default:
	      FIXME("Unknown type parameter = %lx\n", type);
	      flag = SHGDN_FORPARSING | SHGDN_FORADDRESSBAR;
	      break;
	  }
	  if (!*(LPWORD)pidl || type == ILGDN_FORPARSING)
	  {
	    ret = IShellFolder_GetDisplayNameOf(lsf, pidl, flag, &strret);
	    if (SUCCEEDED(ret))
	    {
	      ret = StrRetToStrNW(path, MAX_PATH, &strret, pidl);
	    }
	  }
	  else
	  {
	    ret = SHBindToParent(pidl, &IID_IShellFolder, (LPVOID*)&psfParent, &pidllast);
	    if (SUCCEEDED(ret))
	    {
	      ret = IShellFolder_GetDisplayNameOf(psfParent, pidllast, flag, &strret);
	      if (SUCCEEDED(ret))
	      {
	        ret = StrRetToStrNW(path, MAX_PATH, &strret, pidllast);
	      }
	      IShellFolder_Release(psfParent);
	    }
	  }
	}

	TRACE("%p %p %s\n", psf, pidl, debugstr_w(path));

	if (!psf)
	  IShellFolder_Release(lsf);
	return SUCCEEDED(ret);
}

BOOL WINAPI ILGetDisplayNameEx(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, LPVOID path, DWORD type)
{
	TRACE_(shell)("%p %p %p %ld\n", psf, pidl, path, type);
	if (SHELL_OsIsUnicode())
	  return ILGetDisplayNameExW(psf, pidl, path, type);
	return ILGetDisplayNameExA(psf, pidl, path, type);
}

/*************************************************************************
 * ILGetDisplayName			[SHELL32.15]
 */
BOOL WINAPI ILGetDisplayName(LPCITEMIDLIST pidl, LPVOID path)
{
	TRACE_(shell)("%p %p\n", pidl, path);
	if (SHELL_OsIsUnicode())
	  return ILGetDisplayNameExW(NULL, pidl, path, ILGDN_FORPARSING);
	return ILGetDisplayNameExA(NULL, pidl, path, ILGDN_FORPARSING);
}

/*************************************************************************
 * ILFindLastID [SHELL32.16]
 *
 * NOTES
 *   observed: pidl=Desktop return=pidl
 */
LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
{
	LPCITEMIDLIST   pidlLast = pidl;

	TRACE("(pidl=%p)\n",pidl);

	if (!pidl)
	  return NULL;

	while (pidl->mkid.cb)
	{
	  pidlLast = pidl;
	  pidl = ILGetNext(pidl);
	}
	return (LPITEMIDLIST)pidlLast;
}
/*************************************************************************
 * ILRemoveLastID [SHELL32.17]
 *
 * NOTES
 *   when pidl=Desktop return=FALSE
 */
BOOL WINAPI ILRemoveLastID(LPITEMIDLIST pidl)
{
	TRACE_(shell)("pidl=%p\n",pidl);

	if (!pidl || !pidl->mkid.cb)
	  return 0;
	ILFindLastID(pidl)->mkid.cb = 0;
	return 1;
}

/*************************************************************************
 * ILClone [SHELL32.18]
 *
 * NOTES
 *    duplicate an idlist
 */
LPITEMIDLIST WINAPI ILClone (LPCITEMIDLIST pidl)
{ DWORD    len;
  LPITEMIDLIST  newpidl;

  if (!pidl)
    return NULL;

  len = ILGetSize(pidl);
  newpidl = (LPITEMIDLIST)SHAlloc(len);
  if (newpidl)
    memcpy(newpidl,pidl,len);

  TRACE("pidl=%p newpidl=%p\n",pidl, newpidl);
  pdump(pidl);

  return newpidl;
}
/*************************************************************************
 * ILCloneFirst [SHELL32.19]
 *
 * NOTES
 *  duplicates the first idlist of a complex pidl
 */
LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST pidl)
{	DWORD len;
	LPITEMIDLIST pidlNew = NULL;

	TRACE("pidl=%p \n",pidl);
	pdump(pidl);

	if (pidl)
	{
	  len = pidl->mkid.cb;
	  pidlNew = (LPITEMIDLIST) SHAlloc (len+2);
	  if (pidlNew)
	  {
	    memcpy(pidlNew,pidl,len+2);		/* 2 -> mind a desktop pidl */

	    if (len)
	      ILGetNext(pidlNew)->mkid.cb = 0x00;
	  }
	}
	TRACE("-- newpidl=%p\n",pidlNew);

	return pidlNew;
}

/*************************************************************************
 * ILLoadFromStream (SHELL32.26)
 *
 * NOTES
 *   the first two bytes are the len, the pidl is following then
 */
HRESULT WINAPI ILLoadFromStream (IStream * pStream, LPITEMIDLIST * ppPidl)
{	WORD		wLen = 0;
	DWORD		dwBytesRead;
	HRESULT		ret = E_FAIL;


	TRACE_(shell)("%p %p\n", pStream ,  ppPidl);

	if (*ppPidl)
	{ SHFree(*ppPidl);
	  *ppPidl = NULL;
	}

	IStream_AddRef (pStream);

	if (SUCCEEDED(IStream_Read(pStream, (LPVOID)&wLen, 2, &dwBytesRead)))
	{
	  TRACE("PIDL length is %d\n", wLen);
	  if (wLen != 0) {
	    *ppPidl = SHAlloc (wLen);
	    if (SUCCEEDED(IStream_Read(pStream, *ppPidl , wLen, &dwBytesRead))) {
		TRACE("Stream read OK\n");
		ret = S_OK;
	    } else {
		WARN("reading pidl failed\n");
		SHFree(*ppPidl);
		*ppPidl = NULL;
	    }
	  } else {
	    *ppPidl = NULL;
	    ret = S_OK;
	  }
	}

	/* we are not yet fully compatible */
	if (*ppPidl && !pcheck(*ppPidl))
	{
	  WARN("Check failed\n");
	  SHFree(*ppPidl);
	  *ppPidl = NULL;
	}

	
	IStream_Release (pStream);
	TRACE("done\n");
	return ret;
}

/*************************************************************************
 * ILSaveToStream (SHELL32.27)
 *
 * NOTES
 *   the first two bytes are the len, the pidl is following then
 */
HRESULT WINAPI ILSaveToStream (IStream * pStream, LPCITEMIDLIST pPidl)
{
	LPCITEMIDLIST	pidl;
	WORD		wLen = 0;
	HRESULT		ret = E_FAIL;

	TRACE_(shell)("%p %p\n", pStream, pPidl);

	IStream_AddRef (pStream);

	pidl = pPidl;
        while (pidl->mkid.cb)
        {
          wLen += sizeof(WORD) + pidl->mkid.cb;
          pidl = ILGetNext(pidl);
        }

	if (SUCCEEDED(IStream_Write(pStream, (LPVOID)&wLen, 2, NULL)))
	{
	  if (SUCCEEDED(IStream_Write(pStream, pPidl, wLen, NULL)))
	  { ret = S_OK;
	  }
	}
	IStream_Release (pStream);

	return ret;
}

/*************************************************************************
 * SHILCreateFromPath        [SHELL32.28]
 *
 * Create an ItemIDList from a path
 *
 * PARAMS
 *  path       [I]
 *  ppidl      [O]
 *  attributes [I/O] requested attributes on call and actual attributes when
 *                   the function returns
 *
 * RETURNS
 *  NO_ERROR if successful, or an OLE errer code otherwise
 *
 * NOTES
 *  Wrapper for IShellFolder_ParseDisplayName().
 */
HRESULT WINAPI SHILCreateFromPathA(LPCSTR path, LPITEMIDLIST * ppidl, DWORD * attributes)
{
	LPSHELLFOLDER sf;
	WCHAR lpszDisplayName[MAX_PATH];
	DWORD pchEaten;
	HRESULT ret = E_FAIL;

	TRACE_(shell)("%s %p 0x%08lx\n", path, ppidl, attributes ? *attributes : 0);

	if (!MultiByteToWideChar(CP_ACP, 0, path, -1, lpszDisplayName, MAX_PATH))
	  lpszDisplayName[MAX_PATH-1] = 0;

	if (SUCCEEDED (SHGetDesktopFolder(&sf)))
	{
	  ret = IShellFolder_ParseDisplayName(sf, 0, NULL, lpszDisplayName, &pchEaten, ppidl, attributes);
	  IShellFolder_Release(sf);
	}
	return ret;
}

HRESULT WINAPI SHILCreateFromPathW(LPCWSTR path, LPITEMIDLIST * ppidl, DWORD * attributes)
{
	LPSHELLFOLDER sf;
	DWORD pchEaten;
	HRESULT ret = E_FAIL;

	TRACE_(shell)("%s %p 0x%08lx\n", debugstr_w(path), ppidl, attributes ? *attributes : 0);

	if (SUCCEEDED (SHGetDesktopFolder(&sf)))
	{
	  ret = IShellFolder_ParseDisplayName(sf, 0, NULL, (LPWSTR)path, &pchEaten, ppidl, attributes);
	  IShellFolder_Release(sf);
	}
	return ret;
}

HRESULT WINAPI SHILCreateFromPathAW (LPCVOID path, LPITEMIDLIST * ppidl, DWORD * attributes)
{
	if ( SHELL_OsIsUnicode())
	  return SHILCreateFromPathW (path, ppidl, attributes);
	return SHILCreateFromPathA (path, ppidl, attributes);
}

/*************************************************************************
 * SHCloneSpecialIDList      [SHELL32.89]
 *
 * Create an ItemIDList to one of the special folders.

 * PARAMS
 *  hwndOwner	[in]
 *  nFolder		[in]	CSIDL_xxxxx
 *  fCreate		[in]	Create folder if it does not exist
 *
 * RETURNS
 *  Success: The newly created pidl
 *  Failure: NULL, if inputs are invalid.
 *
 * NOTES
 *  exported by ordinal.
 *  Caller is responsible for deallocating the returned ItemIDList with the
 *  shells IMalloc interface, aka ILFree.
 */
LPITEMIDLIST WINAPI SHCloneSpecialIDList(HWND hwndOwner, DWORD nFolder, BOOL fCreate)
{	LPITEMIDLIST ppidl;
	TRACE_(shell)("(hwnd=%p,csidl=0x%lx,%s).\n", hwndOwner, nFolder, fCreate ? "T" : "F");

	if (fCreate)
	  nFolder |= CSIDL_FLAG_CREATE;

	SHGetSpecialFolderLocation(hwndOwner, nFolder, &ppidl);
	return ppidl;
}

/*************************************************************************
 * ILGlobalClone             [SHELL32.20]
 *
 * Clones an ItemIDList using Alloc.
 *
 * PARAMS
 *  pidl       [I]   ItemIDList to clone
 *
 * RETURNS
 *  Newly allocated ItemIDList.
 *
 * NOTES
 *  exported by ordinal.
 */
LPITEMIDLIST WINAPI ILGlobalClone(LPCITEMIDLIST pidl)
{	DWORD    len;
	LPITEMIDLIST  newpidl;

	if (!pidl)
	  return NULL;

	len = ILGetSize(pidl);
	newpidl = (LPITEMIDLIST)Alloc(len);
	if (newpidl)
	  memcpy(newpidl,pidl,len);

	TRACE("pidl=%p newpidl=%p\n",pidl, newpidl);
	pdump(pidl);

	return newpidl;
}

/*************************************************************************
 * ILIsEqual [SHELL32.21]
 *
 */
BOOL WINAPI ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
{
	char	szData1[MAX_PATH];
	char	szData2[MAX_PATH];

	LPCITEMIDLIST pidltemp1 = pidl1;
	LPCITEMIDLIST pidltemp2 = pidl2;

	TRACE("pidl1=%p pidl2=%p\n",pidl1, pidl2);

	/* explorer reads from registry directly (StreamMRU),
	   so we can only check here */
	if ((!pcheck (pidl1)) || (!pcheck (pidl2))) return FALSE;

	pdump (pidl1);
	pdump (pidl2);

	if ( (!pidl1) || (!pidl2) ) return FALSE;

	while (pidltemp1->mkid.cb && pidltemp2->mkid.cb)
	{
	    _ILSimpleGetText(pidltemp1, szData1, MAX_PATH);
	    _ILSimpleGetText(pidltemp2, szData2, MAX_PATH);

	    if (strcasecmp ( szData1, szData2 )!=0 )
	      return FALSE;

	    pidltemp1 = ILGetNext(pidltemp1);
	    pidltemp2 = ILGetNext(pidltemp2);
	}

	if (!pidltemp1->mkid.cb && !pidltemp2->mkid.cb)
	{
	  return TRUE;
	}

	return FALSE;
}
/*************************************************************************
 * ILIsParent                [SHELL32.23]
 *
 * Verifies that pidlParent is indeed the (immediate) parent of pidlChild.
 *
 * PARAMS
 *  pidlParent [I]
 *  pidlChild  [I]
 *  bImmediate [I]   only return true if the parent is the direct parent
 *                   of the child
 *
 * RETURNS
 *  True if the parent ItemIDlist is a complete part of the child ItemIdList,
 *  False otherwise.
 *
 * NOTES
 *  parent = a/b, child = a/b/c -> true, c is in folder a/b
 *  child = a/b/c/d -> false if bImmediate is true, d is not in folder a/b
 *  child = a/b/c/d -> true if bImmediate is false, d is in a subfolder of a/b
 */
BOOL WINAPI ILIsParent(LPCITEMIDLIST pidlParent, LPCITEMIDLIST pidlChild, BOOL bImmediate)
{
	char	szData1[MAX_PATH];
	char	szData2[MAX_PATH];

	LPCITEMIDLIST pParent = pidlParent;
	LPCITEMIDLIST pChild = pidlChild;

	TRACE("%p %p %x\n", pidlParent, pidlChild, bImmediate);

	if (!pParent || !pChild) return FALSE;

	while (pParent->mkid.cb && pChild->mkid.cb)
	{
	  _ILSimpleGetText(pParent, szData1, MAX_PATH);
	  _ILSimpleGetText(pChild, szData2, MAX_PATH);

	  if (strcasecmp ( szData1, szData2 )!=0 )
	    return FALSE;

	  pParent = ILGetNext(pParent);
	  pChild = ILGetNext(pChild);
	}

	if ( pParent->mkid.cb || ! pChild->mkid.cb) /* child shorter or has equal length to parent */
	  return FALSE;

	if ( ILGetNext(pChild)->mkid.cb && bImmediate) /* not immediate descent */
	  return FALSE;

	return TRUE;
}

/*************************************************************************
 * ILFindChild               [SHELL32.24]
 *
 *  Compares elements from pidl1 and pidl2.
 *
 * PARAMS
 *  pidl1      [I]
 *  pidl2      [I]
 *
 * RETURNS
 *  pidl1 is desktop      pidl2
 *  pidl1 shorter pidl2   pointer to first different element of pidl2
 *                        if there was at least one equal element
 *  pidl2 shorter pidl1   0
 *  pidl2 equal pidl1     pointer to last 0x00-element of pidl2
 *
 * NOTES
 *  exported by ordinal.
 */
LPITEMIDLIST WINAPI ILFindChild(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
{
	char	szData1[MAX_PATH];
	char	szData2[MAX_PATH];

	LPCITEMIDLIST pidltemp1 = pidl1;
	LPCITEMIDLIST pidltemp2 = pidl2;
	LPCITEMIDLIST ret=NULL;

	TRACE("pidl1=%p pidl2=%p\n",pidl1, pidl2);

	/* explorer reads from registry directly (StreamMRU),
	   so we can only check here */
	if ((!pcheck (pidl1)) || (!pcheck (pidl2)))
	  return FALSE;

	pdump (pidl1);
	pdump (pidl2);

	if ( _ILIsDesktop(pidl1) )
	{
	  ret = pidl2;
	}
	else
	{
	  while (pidltemp1->mkid.cb && pidltemp2->mkid.cb)
	  {
	    _ILSimpleGetText(pidltemp1, szData1, MAX_PATH);
	    _ILSimpleGetText(pidltemp2, szData2, MAX_PATH);

	    if (strcasecmp(szData1,szData2))
	      break;

	    pidltemp1 = ILGetNext(pidltemp1);
	    pidltemp2 = ILGetNext(pidltemp2);
	    ret = pidltemp2;
	  }

	  if (pidltemp1->mkid.cb)
	  {
	    ret = NULL; /* elements of pidl1 left*/
	  }
	}
	TRACE_(shell)("--- %p\n", ret);
	return (LPITEMIDLIST)ret; /* pidl 1 is shorter */
}

/*************************************************************************
 * ILCombine                 [SHELL32.25]
 *
 * Concatenates two complex ItemIDLists.
 *
 * PARAMS
 *  pidl1      [I]   first complex ItemIDLists
 *  pidl2      [I]   complex ItemIDLists to append
 *
 * RETURNS
 *  if both pidl's == NULL      NULL
 *  if pidl1 == NULL            cloned pidl2
 *  if pidl2 == NULL            cloned pidl1
 *  otherwise new pidl with pidl2 appended to pidl1
 *
 * NOTES
 *  exported by ordinal.
 *  Does not destroy the passed in ItemIDLists!
 */
LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
{
	DWORD    len1,len2;
	LPITEMIDLIST  pidlNew;

	TRACE("pidl=%p pidl=%p\n",pidl1,pidl2);

	if(!pidl1 && !pidl2) return NULL;

	pdump (pidl1);
	pdump (pidl2);

	if(!pidl1)
	{
	  pidlNew = ILClone(pidl2);
	  return pidlNew;
	}

	if(!pidl2)
	{
	  pidlNew = ILClone(pidl1);
	  return pidlNew;
	}

	len1  = ILGetSize(pidl1)-2;
	len2  = ILGetSize(pidl2);
	pidlNew  = SHAlloc(len1+len2);

	if (pidlNew)
	{
	  memcpy(pidlNew,pidl1,len1);
	  memcpy(((BYTE *)pidlNew)+len1,pidl2,len2);
	}

	/*  TRACE(pidl,"--new pidl=%p\n",pidlNew);*/
	return pidlNew;
}

/*************************************************************************
 *  SHGetRealIDL [SHELL32.98]
 *
 * NOTES
 */
HRESULT WINAPI SHGetRealIDL(LPSHELLFOLDER lpsf, LPCITEMIDLIST pidlSimple, LPITEMIDLIST *pidlReal)
{
	IDataObject* pDataObj;
	HRESULT hr = IShellFolder_GetUIObjectOf(lpsf, 0, 1, &pidlSimple, &IID_IDataObject, 0, (LPVOID*)&pDataObj);

	if (SUCCEEDED(hr)) {
            STGMEDIUM medium;
            FORMATETC fmt;

            fmt.cfFormat = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
            fmt.ptd = NULL;
            fmt.dwAspect = DVASPECT_CONTENT;
            fmt.lindex = -1;
            fmt.tymed = TYMED_HGLOBAL;

	    hr = IDataObject_GetData(pDataObj, &fmt, &medium);

	    IDataObject_Release(pDataObj);

	    if (SUCCEEDED(hr)) {
		/*assert(pida->cidl==1);*/
		LPIDA pida = (LPIDA)GlobalLock(medium.u.hGlobal);

		LPCITEMIDLIST pidl_folder = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[0]);
		LPCITEMIDLIST pidl_child = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[1]);

		*pidlReal = ILCombine(pidl_folder, pidl_child);

		if (!*pidlReal)
			hr = E_OUTOFMEMORY;

		GlobalUnlock(medium.u.hGlobal);
		GlobalFree(medium.u.hGlobal);
	    }
	}

	return hr;
}

/*************************************************************************
 *  SHLogILFromFSIL [SHELL32.95]
 *
 * NOTES
 *  pild = CSIDL_DESKTOP	ret = 0
 *  pild = CSIDL_DRIVES		ret = 0
 */
LPITEMIDLIST WINAPI SHLogILFromFSIL(LPITEMIDLIST pidl)
{
	FIXME("(pidl=%p)\n",pidl);

	pdump(pidl);

	return 0;
}

/*************************************************************************
 * ILGetSize                 [SHELL32.152]
 *
 * Gets the byte size of an ItemIDList including zero terminator
 *
 * PARAMS
 *  pidl       [I]   ItemIDList
 *
 * RETURNS
 *  size of pidl in bytes
 *
 * NOTES
 *  exported by ordinal
 */
UINT WINAPI ILGetSize(LPCITEMIDLIST pidl)
{
	LPCSHITEMID si = &(pidl->mkid);
	UINT len=0;

	if (pidl)
	{ while (si->cb)
	  { len += si->cb;
	    si  = (LPSHITEMID)(((LPBYTE)si)+si->cb);
	  }
	  len += 2;
	}
	TRACE("pidl=%p size=%u\n",pidl, len);
	return len;
}

/*************************************************************************
 * ILGetNext                 [SHELL32.153]
 *
 * Gets the next ItemID of an ItemIDList
 *
 * PARAMS
 *  pidl       [I]   ItemIDList
 *
 * RETURNS
 *  null -> null
 *  desktop -> null
 *  simple pidl -> pointer to 0x0000 element
 *
 * NOTES
 *  exported by ordinal.
 */
LPITEMIDLIST WINAPI ILGetNext(LPCITEMIDLIST pidl)
{
	WORD len;

	TRACE("%p\n", pidl);

	if(pidl)
	{
	  len =  pidl->mkid.cb;
	  if (len)
	  {
	    pidl = (LPITEMIDLIST) (((LPBYTE)pidl)+len);
	    TRACE("-- %p\n", pidl);
	    return (LPITEMIDLIST)pidl;
	  }
	}
	return NULL;
}

/*************************************************************************
 * ILAppend                  [SHELL32.154]
 *
 * Adds the single ItemID item to the ItemIDList indicated by pidl.
 * If bEnd is FALSE, inserts the item in the front of the list,
 * otherwise it adds the item to the end. (???)
 *
 * PARAMS
 *  pidl       [I]   ItemIDList to extend
 *  item       [I]   ItemID to prepend/append
 *  bEnd       [I]   Indicates if the item should be appended
 *
 * NOTES
 *  Destroys the passed in idlist! (???)
 */
LPITEMIDLIST WINAPI ILAppend(LPITEMIDLIST pidl, LPCITEMIDLIST item, BOOL bEnd)
{
	LPITEMIDLIST idlRet;

	WARN("(pidl=%p,pidl=%p,%08u)semi-stub\n",pidl,item,bEnd);

	pdump (pidl);
	pdump (item);

	if (_ILIsDesktop(pidl))
	{
	   idlRet = ILClone(item);
	   if (pidl)
	     SHFree (pidl);
	   return idlRet;
	}

	if (bEnd)
	{
	  idlRet = ILCombine(pidl, item);
	}
	else
	{
	  idlRet = ILCombine(item, pidl);
	}

	SHFree(pidl);
	return idlRet;
}

/*************************************************************************
 * ILFree                    [SHELL32.155]
 *
 * Frees memory (if not NULL) allocated by SHMalloc allocator
 *
 * PARAMS
 *  pidl         [I]
 *
 * NOTES
 *  exported by ordinal
 */
void WINAPI ILFree(LPITEMIDLIST pidl)
{
	TRACE("(pidl=%p)\n",pidl);
	if(pidl) SHFree(pidl);
}

/*************************************************************************
 * ILGlobalFree              [SHELL32.156]
 *
 * Frees memory (if not NULL) allocated by Alloc allocator
 *
 * PARAMS
 *  pidl         [I]
 *
 * NOTES
 *  exported by ordinal.
 */
void WINAPI ILGlobalFree( LPITEMIDLIST pidl)
{
	TRACE("%p\n", pidl);

	if(!pidl) return;
	Free(pidl);
}

/*************************************************************************
 * ILCreateFromPathA         [SHELL32.189]
 *
 * Creates a complex ItemIDList from a path and returns it.
 *
 * PARAMS
 *  path         [I]
 *
 * RETURNS
 *  the newly created complex ItemIDList or NULL if failed
 *
 * NOTES
 *  exported by ordinal.
 */

LPITEMIDLIST WINAPI ILCreateFromPathA (LPCSTR path)
{
	LPITEMIDLIST pidlnew = NULL;

	TRACE_(shell)("%s\n", debugstr_a(path));

	if (SUCCEEDED(SHILCreateFromPathA(path, &pidlnew, NULL)))
	  return pidlnew;
	return NULL;
}

/*************************************************************************
 * ILCreateFromPathW         [SHELL32.190]
 */
LPITEMIDLIST WINAPI ILCreateFromPathW (LPCWSTR path)
{
	LPITEMIDLIST pidlnew = NULL;

	TRACE_(shell)("%s\n", debugstr_w(path));

	if (SUCCEEDED(SHILCreateFromPathW(path, &pidlnew, NULL)))
	  return pidlnew;
	return NULL;
}

/*************************************************************************
 * ILCreateFromPath          [SHELL32.157]
 */
LPITEMIDLIST WINAPI ILCreateFromPathAW (LPCVOID path)
{
	if ( SHELL_OsIsUnicode())
	  return ILCreateFromPathW (path);
	return ILCreateFromPathA (path);
}

/*************************************************************************
 * _ILParsePathW             [internal]
 *
 * Creates an ItemIDList from a path and returns it.
 *
 * PARAMS
 *  path         [I]   path to parse and convert into an ItemIDList
 *  lpFindFile   [I]   pointer to buffer to initialize the FileSystem
 *                     Bind Data object with
 *  bBindCtx     [I]   indicates to create a BindContext and assign a
 *                     FileSystem Bind Data object
 *  ppidl        [O]   the newly create ItemIDList
 *  prgfInOut    [I/O] requested attributes on input and actual
 *                     attributes on return
 *
 * RETURNS
 *  NO_ERROR on success or an OLE error code
 *
 * NOTES
 *  If either lpFindFile is non-NULL or bBindCtx is TRUE, this function
 *  creates a BindContext object and assigns a FileSystem Bind Data object
 *  to it, passing the BindContext to IShellFolder_ParseDisplayName. Each
 *  IShellFolder uses that FileSystem Bind Data object of the BindContext
 *  to pass data about the current path element to the next object. This
 *  is used to avoid having to verify the current path element on disk, so
 *  that creating an ItemIDList from a non-existent path still can work.
 */
static HRESULT WINAPI _ILParsePathW(LPCWSTR path, LPWIN32_FIND_DATAW lpFindFile,
                             BOOL bBindCtx, LPITEMIDLIST *ppidl, LPDWORD prgfInOut)
{
	LPSHELLFOLDER pSF = NULL;
	LPBC pBC = NULL;
	HRESULT ret;

	TRACE("%s %p %d (%p)->%p (%p)->0x%lx\n", debugstr_w(path), lpFindFile, bBindCtx,
	                                         ppidl, ppidl ? *ppidl : NULL,
	                                         prgfInOut, prgfInOut ? *prgfInOut : 0);

	ret = SHGetDesktopFolder(&pSF);
	if (FAILED(ret))
	{
	  return ret;
	}

	if (lpFindFile || bBindCtx)
	  ret = IFileSystemBindData_Constructor(lpFindFile, &pBC);

	if (SUCCEEDED(ret))
	{
	  ret = IShellFolder_ParseDisplayName(pSF, 0, pBC, (LPOLESTR)path, NULL, ppidl, prgfInOut);
	}

	if (pBC)
	{
	  IBindCtx_Release(pBC);
	  pBC = NULL;
	}

	IShellFolder_Release(pSF);

	if (!SUCCEEDED(ret) && ppidl)
	  *ppidl = NULL;

	TRACE("%s %p 0x%lx\n", debugstr_w(path), ppidl ? *ppidl : NULL, prgfInOut ? *prgfInOut : 0);

	return ret;
}

/*************************************************************************
 * SHSimpleIDListFromPath    [SHELL32.162]
 *
 * Creates a simple ItemIDList from a path and returns it. This function
 * does not fail on non-existent paths.
 *
 * PARAMS
 *  path         [I]   path to parse and convert into an ItemIDList
 *
 * RETURNS
 *  the newly created simple ItemIDList
 *
 * NOTES
 *  Simple in the name does not mean a relative ItemIDList but rather a
 *  fully qualified list, where only the file name is filled in and the
 *  directory flag for those ItemID elements this is known about, eg.
 *  it is not the last element in the ItemIDList or the actual directory
 *  exists on disk.
 *  exported by ordinal.
 */
LPITEMIDLIST WINAPI SHSimpleIDListFromPathA(LPCSTR lpszPath)
{
    LPITEMIDLIST pidl = NULL;
    LPWSTR wPath = NULL;
    int len;

    TRACE("%s\n", debugstr_a(lpszPath));

    if (lpszPath)
    {
        len = MultiByteToWideChar(CP_ACP, 0, lpszPath, -1, NULL, 0);
        wPath = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
        MultiByteToWideChar(CP_ACP, 0, lpszPath, -1, wPath, len);
    }

    _ILParsePathW(wPath, NULL, TRUE, &pidl, NULL);

    if (wPath) HeapFree(GetProcessHeap(), 0, wPath);
    TRACE("%s %p\n", debugstr_a(lpszPath), pidl);
    return pidl;
}

LPITEMIDLIST WINAPI SHSimpleIDListFromPathW(LPCWSTR lpszPath)
{
	LPITEMIDLIST pidl = NULL;

	TRACE("%s\n", debugstr_w(lpszPath));

	_ILParsePathW(lpszPath, NULL, TRUE, &pidl, NULL);
	TRACE("%s %p\n", debugstr_w(lpszPath), pidl);
	return pidl;
}

LPITEMIDLIST WINAPI SHSimpleIDListFromPathAW(LPCVOID lpszPath)
{
	if ( SHELL_OsIsUnicode())
	  return SHSimpleIDListFromPathW (lpszPath);
	return SHSimpleIDListFromPathA (lpszPath);
}

/*************************************************************************
 * SHGetDataFromIDListA [SHELL32.247]
 *
 * NOTES
 *  the pidl can be a simple one. since we can't get the path out of the pidl
 *  we have to take all data from the pidl
 */
HRESULT WINAPI SHGetDataFromIDListA(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, int nFormat, LPVOID dest, int len)
{
	TRACE_(shell)("sf=%p pidl=%p 0x%04x %p 0x%04x stub\n",psf,pidl,nFormat,dest,len);

	pdump(pidl);
	if (!psf || !dest )  return E_INVALIDARG;

	switch (nFormat)
	{
	  case SHGDFIL_FINDDATA:
	    {
	       LPSTR filename, shortname;
	       WIN32_FIND_DATAA * pfd = dest;

	       if (_ILIsDrive(pidl))
	           return E_INVALIDARG;

	       if (len < (int)sizeof(WIN32_FIND_DATAA)) return E_INVALIDARG;

	       ZeroMemory(pfd, sizeof (WIN32_FIND_DATAA));
	       _ILGetFileDateTime( pidl, &(pfd->ftLastWriteTime));
	       pfd->dwFileAttributes = _ILGetFileAttributes(pidl, NULL, 0);
	       pfd->nFileSizeLow = _ILGetFileSize ( pidl, NULL, 0);

	       filename = _ILGetTextPointer(pidl);
	       shortname = _ILGetSTextPointer(pidl);

	       if (filename)
	           lstrcpynA(pfd->cFileName, filename, MAX_PATH);
	       else
	           pfd->cFileName[0] = '\0';

	       if (shortname)
	           lstrcpynA(pfd->cAlternateFileName, shortname, MAX_PATH);
	       else
	           pfd->cAlternateFileName[0] = '\0';
	    }
	    return NOERROR;

	  case SHGDFIL_NETRESOURCE:
	  case SHGDFIL_DESCRIPTIONID:
	    FIXME_(shell)("SHGDFIL %i stub\n", nFormat);
	    break;

	  default:
	    ERR_(shell)("Unknown SHGDFIL %i, please report\n", nFormat);
	}

	return E_INVALIDARG;
}

/*************************************************************************
 * SHGetDataFromIDListW [SHELL32.248]
 *
 */
HRESULT WINAPI SHGetDataFromIDListW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, int nFormat, LPVOID dest, int len)
{
	TRACE_(shell)("sf=%p pidl=%p 0x%04x %p 0x%04x stub\n",psf,pidl,nFormat,dest,len);

	pdump(pidl);

	if (! psf || !dest )  return E_INVALIDARG;

	switch (nFormat)
	{
	  case SHGDFIL_FINDDATA:
	    {
	       LPSTR filename, shortname;
	       WIN32_FIND_DATAW * pfd = dest;

	       if (_ILIsDrive(pidl))
	           return E_INVALIDARG;

	       if (len < (int)sizeof(WIN32_FIND_DATAW)) return E_INVALIDARG;

	       ZeroMemory(pfd, sizeof (WIN32_FIND_DATAA));
	       _ILGetFileDateTime( pidl, &(pfd->ftLastWriteTime));
	       pfd->dwFileAttributes = _ILGetFileAttributes(pidl, NULL, 0);
	       pfd->nFileSizeLow = _ILGetFileSize ( pidl, NULL, 0);

	       filename = _ILGetTextPointer(pidl);
	       shortname = _ILGetSTextPointer(pidl);

	       if (!filename)
	           pfd->cFileName[0] = '\0';
	       else if (!MultiByteToWideChar(CP_ACP, 0, filename, -1, pfd->cFileName, MAX_PATH))
	           pfd->cFileName[MAX_PATH-1] = 0;

	       if (!shortname)
	           pfd->cAlternateFileName[0] = '\0';
	       else if (!MultiByteToWideChar(CP_ACP, 0, shortname, -1, pfd->cAlternateFileName, 14))
	           pfd->cAlternateFileName[13] = 0;
	    }
	    return NOERROR;
	  case SHGDFIL_NETRESOURCE:
	  case SHGDFIL_DESCRIPTIONID:
	    FIXME_(shell)("SHGDFIL %i stub\n", nFormat);
	    break;

	  default:
	    ERR_(shell)("Unknown SHGDFIL %i, please report\n", nFormat);
	}

	return E_INVALIDARG;
}

/*************************************************************************
 * SHELL_GetPathFromIDListA
 */
HRESULT SHELL_GetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath, UINT uOutSize)
{
	HRESULT hr = S_OK;

        pszPath[0]=0;

	/* One case is a PIDL rooted at desktop level */
	if (_ILIsValue(pidl) || _ILIsFolder(pidl)) {
	    hr = SHGetSpecialFolderPathA(0, pszPath, CSIDL_DESKTOP, FALSE);

	    if (SUCCEEDED(hr))
		PathAddBackslashA(pszPath);
	}
	/* The only other valid case is a item ID list beginning at "My Computer" */
 	else if (_ILIsMyComputer(pidl))
	    pidl = ILGetNext(pidl);

        if (SUCCEEDED(hr)) {
	    LPSTR txt;

	    while(pidl && pidl->mkid.cb) {
		if (_ILIsSpecialFolder(pidl))
		    {hr = E_INVALIDARG; break;}

		txt = _ILGetTextPointer(pidl);
		if (!txt)
		    {hr = E_INVALIDARG; break;}

                if (lstrlenA(txt) > pidl->mkid.cb)
                    ERR("pidl %p is borked\n",pidl);

                /* make sure there's enough space for the next segment */
                if ( (lstrlenA(txt) + lstrlenA(pszPath)) > uOutSize)
		    {hr = E_INVALIDARG; break;}
		lstrcatA( pszPath, txt );

		pidl = ILGetNext(pidl);
		if (!pidl)
		    {hr = E_INVALIDARG; break;}

		if (!pidl->mkid.cb) {
		    /* We are at the end and successfully converted the complete PIDL. */
		    break;
		}

                if( (lstrlenA(pszPath) + 1) > uOutSize)
		    {hr = E_INVALIDARG; break;}
		if (!PathAddBackslashA(pszPath))
		    {hr = E_INVALIDARG; break;}
	    }
	} else
	    hr = E_INVALIDARG;

	TRACE_(shell)("-- %s, 0x%08lx\n", pszPath, hr);
	return hr;
}

/*************************************************************************
 * SHGetPathFromIDListA		[SHELL32.@][NT 4.0: SHELL32.220]
 *
 * PARAMETERS
 *  pidl,   [IN] pidl
 *  pszPath [OUT] path
 *
 * RETURNS
 *  path from a passed PIDL.
 *
 * NOTES
 *	NULL returns FALSE
 *	desktop pidl gives path to desktop directory back
 *	special pidls returning FALSE
 */
BOOL WINAPI SHGetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath)
{
	HRESULT hr;

	TRACE_(shell)("(pidl=%p,%p)\n",pidl,pszPath);
	pdump(pidl);

	if (!pidl)
	    return FALSE;

	hr = SHELL_GetPathFromIDListA(pidl, pszPath, MAX_PATH);

	return SUCCEEDED(hr);
}

/*************************************************************************
 * SHELL_GetPathFromIDListW
 */
HRESULT SHELL_GetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath, UINT uOutSize)
{
	HRESULT hr = S_OK;
	UINT len;

        pszPath[0]=0;

	/* One case is a PIDL rooted at desktop level */
	if (_ILIsValue(pidl) || _ILIsFolder(pidl)) {
	    hr = SHGetSpecialFolderPathW(0, pszPath, CSIDL_DESKTOP, FALSE);

	    if (SUCCEEDED(hr))
		PathAddBackslashW(pszPath);
	}
	/* The only other valid case is a item ID list beginning at "My Computer" */
 	else if (_ILIsMyComputer(pidl))
	    pidl = ILGetNext(pidl);

        if (SUCCEEDED(hr)) {
	    LPSTR txt;

	    while(pidl && pidl->mkid.cb) {
		if (_ILIsSpecialFolder(pidl))
		    {hr = E_INVALIDARG; break;}

		txt = _ILGetTextPointer(pidl);
		if (!txt)
		    {hr = E_INVALIDARG; break;}

                if (lstrlenA(txt) > pidl->mkid.cb)
                    ERR("pidl %p is borked\n",pidl);
		len = MultiByteToWideChar(CP_ACP, 0, txt, -1, NULL, 0);
                if ( (lstrlenW(pszPath) + len) > uOutSize )
		    {hr = E_INVALIDARG; break;}

		MultiByteToWideChar(CP_ACP, 0, txt, -1, 
                                    &pszPath[lstrlenW(pszPath)], len);

		pidl = ILGetNext(pidl);
		if (!pidl)
		    {hr = E_INVALIDARG; break;}

		if (!pidl->mkid.cb) {
		    /* We are at the end and successfully converted the complete PIDL. */
		    break;
		}

                if ( (lstrlenW(pszPath) + 1) > uOutSize )
		    {hr = E_INVALIDARG; break;}
		if (!PathAddBackslashW(pszPath))
		    {hr = E_INVALIDARG; break;}
	    }
	} else
	    hr = E_INVALIDARG;

    TRACE_(shell)("-- %s, 0x%08lx\n", debugstr_w(pszPath), hr);
    return hr;
}

/*************************************************************************
 * SHGetPathFromIDListW 			[SHELL32.@]
 */
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
{
	HRESULT hr;

	TRACE_(shell)("(pidl=%p,%p)\n", pidl, debugstr_w(pszPath));
	pdump(pidl);

	if (!pidl)
	    return FALSE;

	hr = SHELL_GetPathFromIDListW(pidl, pszPath, MAX_PATH);

	TRACE_(shell)("-- %s, 0x%08lx\n",debugstr_w(pszPath), hr);
	return SUCCEEDED(hr);
}

/*************************************************************************
 * SHGetPathFromIDList		[SHELL32.@][NT 4.0: SHELL32.219]
 */
BOOL WINAPI SHGetPathFromIDListAW(LPCITEMIDLIST pidl,LPVOID pszPath)
{
	TRACE_(shell)("(pidl=%p,%p)\n",pidl,pszPath);

	if (SHELL_OsIsUnicode())
	  return SHGetPathFromIDListW(pidl,pszPath);
	return SHGetPathFromIDListA(pidl,pszPath);
}

/*************************************************************************
 *	SHBindToParent		[shell version 5.0]
 */
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
{
	IShellFolder	* psf;
	LPITEMIDLIST	pidlChild, pidlParent;
	HRESULT		hr=E_FAIL;

	TRACE_(shell)("pidl=%p\n", pidl);
	pdump(pidl);

	*ppv = NULL;
	if (ppidlLast) *ppidlLast = NULL;

	if (_ILIsPidlSimple(pidl))
	{
	  IShellFolder* desktop;

	  /* we are on desktop level */
	  hr = SHGetDesktopFolder(&desktop);

	  if (SUCCEEDED(hr))
	  {
	    hr = IShellFolder_QueryInterface(desktop, riid, ppv);

	    if (SUCCEEDED(hr) && ppidlLast)
	      *ppidlLast = ILClone(pidl);

	    IShellFolder_Release(desktop);
	  }
	}
	else
	{
	  pidlChild =  ILClone(ILFindLastID(pidl));
	  pidlParent = ILClone(pidl);
	  ILRemoveLastID(pidlParent);

	  hr = SHGetDesktopFolder(&psf);

	  if (SUCCEEDED(hr))
	    hr = IShellFolder_BindToObject(psf, pidlParent, NULL, riid, ppv);

	  if (SUCCEEDED(hr) && ppidlLast)
	    *ppidlLast = pidlChild;
	  else
	    ILFree (pidlChild);

	  SHFree (pidlParent);
	  if (psf) IShellFolder_Release(psf);
	}


	TRACE_(shell)("-- psf=%p pidl=%p ret=0x%08lx\n", *ppv, (ppidlLast)?*ppidlLast:NULL, hr);
	return hr;
}

/**************************************************************************
 *
 *		internal functions
 *
 *	### 1. section creating pidls ###
 *
 *************************************************************************
 */
LPITEMIDLIST _ILAlloc(PIDLTYPE type, size_t size)
{
    LPITEMIDLIST pidlOut = NULL;

    if((pidlOut = SHAlloc(size + 5)))
    {
        LPPIDLDATA pData;
        LPITEMIDLIST pidlNext;

        ZeroMemory(pidlOut, size + 5);
        pidlOut->mkid.cb = size + 3;

        if ((pData = _ILGetDataPointer(pidlOut)))
            pData->type = type;

        if ((pidlNext = ILGetNext(pidlOut)))
            pidlNext->mkid.cb = 0x00;
        TRACE("-- (pidl=%p, size=%u)\n", pidlOut, size);
    }

    return pidlOut;
}

LPITEMIDLIST _ILCreateDesktop()
{
    LPITEMIDLIST ret;

    TRACE("()\n");
    ret = SHAlloc(2);
    if (ret)
        ret->mkid.cb = 0;
    return ret;
}

LPITEMIDLIST _ILCreateMyComputer()
{	TRACE("()\n");
	return _ILCreateGuid(PT_GUID, &CLSID_MyComputer);
}

LPITEMIDLIST _ILCreateIExplore()
{	TRACE("()\n");
	return _ILCreateGuid(PT_GUID, &CLSID_Internet);
}

LPITEMIDLIST _ILCreateControlPanel()
{
    LPITEMIDLIST parent = _ILCreateGuid(PT_GUID, &CLSID_MyComputer), ret = NULL;

    TRACE("()\n");
    if (parent)
    {
        LPITEMIDLIST cpl = _ILCreateGuid(PT_GUID, &CLSID_ControlPanel);

        if (cpl)
        {
            ret = ILCombine(parent, cpl);
            SHFree(cpl);
        }
        SHFree(parent);
    }
    return ret;
}

LPITEMIDLIST _ILCreatePrinters()
{
    LPITEMIDLIST parent = _ILCreateGuid(PT_GUID, &CLSID_MyComputer), ret = NULL;

    TRACE("()\n");
    if (parent)
    {
        LPITEMIDLIST printers = _ILCreateGuid(PT_GUID, &CLSID_Printers);

        if (printers)
        {
            ret = ILCombine(parent, printers);
            SHFree(printers);
        }
        SHFree(parent);
    }
    return ret;
}

LPITEMIDLIST _ILCreateNetwork()
{	TRACE("()\n");
	return _ILCreateGuid(PT_GUID, &CLSID_NetworkPlaces);
}

LPITEMIDLIST _ILCreateBitBucket()
{	TRACE("()\n");
	return _ILCreateGuid(PT_GUID, &CLSID_RecycleBin);
}

LPITEMIDLIST _ILCreateGuid(PIDLTYPE type, REFIID guid)
{
    LPITEMIDLIST pidlOut;

    if (type == PT_SHELLEXT || type == PT_GUID)
    {
        pidlOut = _ILAlloc(type, sizeof(GUIDStruct));
        if (pidlOut)
        {
            LPPIDLDATA pData = _ILGetDataPointer(pidlOut);

            memcpy(&(pData->u.guid.guid), guid, sizeof(GUID));
            TRACE("-- create GUID-pidl %s\n",
             debugstr_guid(&(pData->u.guid.guid)));
        }
    }
    else
    {
        WARN("%d: invalid type for GUID\n", type);
        pidlOut = NULL;
    }
    return pidlOut;
}

LPITEMIDLIST _ILCreateGuidFromStrA(LPCSTR szGUID)
{
	IID iid;

	if (!SUCCEEDED(SHCLSIDFromStringA(szGUID, &iid)))
	{
	  ERR("%s is not a GUID\n", szGUID);
	  return NULL;
	}
	return _ILCreateGuid(PT_GUID, &iid);
}

LPITEMIDLIST _ILCreateFromFindDataA(WIN32_FIND_DATAA * stffile )
{
    char	buff[MAX_PATH + 14 +1]; /* see WIN32_FIND_DATA */
    char *	pbuff = buff;
    size_t	len, len1;
    LPITEMIDLIST pidl;
    PIDLTYPE type;

    if (!stffile)
        return NULL;

    TRACE("(%s, %s)\n",stffile->cAlternateFileName, stffile->cFileName);

    /* prepare buffer with both names */
    len = strlen (stffile->cFileName) + 1;
    memcpy (pbuff, stffile->cFileName, len);
    pbuff += len;

    len1 = strlen (stffile->cAlternateFileName)+1;
    memcpy (pbuff, stffile->cAlternateFileName, len1);

    type = (stffile->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? PT_FOLDER : 
     PT_VALUE;
    /* FileStruct already has one byte for the first name, so use len - 1 in
     * size calculation
     */
    if ((pidl = _ILAlloc(type, sizeof(FileStruct) + (len - 1) + len1)))
    {
        LPPIDLDATA pData;
        LPSTR pszDest;

        /* set attributes */
        if ((pData = _ILGetDataPointer(pidl)))
        {
            pData->type = type;
            FileTimeToDosDateTime(&(stffile->ftLastWriteTime),&pData->u.file.uFileDate,&pData->u.file.uFileTime);
            pData->u.file.dwFileSize = stffile->nFileSizeLow;
            pData->u.file.uFileAttribs = (WORD)stffile->dwFileAttributes;
        }
        if ((pszDest = _ILGetTextPointer(pidl)))
        {
            memcpy(pszDest, buff, len + len1);
            TRACE("-- create Value: %s\n",debugstr_a(pszDest));
        }
    }
    return pidl;
}

HRESULT _ILCreateFromPathA(LPCSTR szPath, LPITEMIDLIST* ppidl)
{
	HANDLE hFile;
	WIN32_FIND_DATAA stffile;

    if (!ppidl)
        return E_INVALIDARG;

	hFile = FindFirstFileA(szPath, &stffile);

	if (hFile == INVALID_HANDLE_VALUE)
		return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);

	FindClose(hFile);

	*ppidl = _ILCreateFromFindDataA(&stffile);

	return *ppidl ? S_OK : E_OUTOFMEMORY;
}

LPITEMIDLIST _ILCreateDrive(LPCWSTR lpszNew)
{
    WCHAR sTemp[4];
    LPITEMIDLIST pidlOut;

    sTemp[0]=toupperW(lpszNew[0]);
    sTemp[1]=':';
    sTemp[2]='\\';
    sTemp[3]=0x00;
    TRACE("(%s)\n",debugstr_w(sTemp));

    if ((pidlOut = _ILAlloc(PT_DRIVE, sizeof(DriveStruct))))
    {
        LPSTR pszDest;

        if ((pszDest = _ILGetTextPointer(pidlOut)))
        {
	    WideCharToMultiByte(CP_ACP, 0, sTemp, sizeof(sTemp)/sizeof(WCHAR), pszDest, sizeof(sTemp)/sizeof(WCHAR), NULL, NULL);
            TRACE("-- create Drive: %s\n", debugstr_a(pszDest));
        }
    }
    return pidlOut;
}

/**************************************************************************
 *  _ILGetDrive()
 *
 *  Gets the text for the drive eg. 'c:\'
 *
 * RETURNS
 *  strlen (lpszText)
 */
DWORD _ILGetDrive(LPCITEMIDLIST pidl,LPSTR pOut, UINT uSize)
{	TRACE("(%p,%p,%u)\n",pidl,pOut,uSize);

	if(_ILIsMyComputer(pidl))
	  pidl = ILGetNext(pidl);

	if (pidl && _ILIsDrive(pidl))
	  return _ILSimpleGetText(pidl, pOut, uSize);

	return 0;
}

/**************************************************************************
 *
 *	### 2. section testing pidls ###
 *
 **************************************************************************
 *  _ILIsDesktop()
 *  _ILIsMyComputer()
 *  _ILIsSpecialFolder()
 *  _ILIsDrive()
 *  _ILIsFolder()
 *  _ILIsValue()
 *  _ILIsPidlSimple()
 */
BOOL _ILIsDesktop(LPCITEMIDLIST pidl)
{	TRACE("(%p)\n",pidl);
	return pidl && pidl->mkid.cb  ? 0 : 1;
}

BOOL _ILIsMyComputer(LPCITEMIDLIST pidl)
{
	REFIID iid = _ILGetGUIDPointer(pidl);

	TRACE("(%p)\n",pidl);

	if (iid)
	  return IsEqualIID(iid, &CLSID_MyComputer);
	return FALSE;
}

BOOL _ILIsSpecialFolder (LPCITEMIDLIST pidl)
{
	LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
	TRACE("(%p)\n",pidl);
	return (pidl && ( (lpPData && (PT_GUID== lpPData->type || PT_SHELLEXT== lpPData->type)) ||
			  (pidl && pidl->mkid.cb == 0x00)
			));
}

BOOL _ILIsDrive(LPCITEMIDLIST pidl)
{	LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
	TRACE("(%p)\n",pidl);
	return (pidl && lpPData && (PT_DRIVE == lpPData->type ||
				    PT_DRIVE1 == lpPData->type ||
				    PT_DRIVE2 == lpPData->type ||
				    PT_DRIVE3 == lpPData->type));
}

BOOL _ILIsFolder(LPCITEMIDLIST pidl)
{	LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
	TRACE("(%p)\n",pidl);
	return (pidl && lpPData && (PT_FOLDER == lpPData->type || PT_FOLDER1 == lpPData->type));
}

BOOL _ILIsValue(LPCITEMIDLIST pidl)
{	LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
	TRACE("(%p)\n",pidl);
	return (pidl && lpPData && PT_VALUE == lpPData->type);
}

BOOL _ILIsCPanelStruct(LPCITEMIDLIST pidl)
{	LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
	TRACE("(%p)\n",pidl);
	return (pidl && lpPData && (lpPData->type == 0));
}

/**************************************************************************
 *	_ILIsPidlSimple
 */
BOOL _ILIsPidlSimple ( LPCITEMIDLIST pidl)
{
	BOOL ret = TRUE;

	if(! _ILIsDesktop(pidl))	/* pidl=NULL or mkid.cb=0 */
	{
	  WORD len = pidl->mkid.cb;
	  LPCITEMIDLIST pidlnext = (LPCITEMIDLIST) (((LPBYTE)pidl) + len );
	  if (pidlnext->mkid.cb)
	    ret = FALSE;
	}

	TRACE("%s\n", ret ? "Yes" : "No");
	return ret;
}

/**************************************************************************
 *
 *	### 3. section getting values from pidls ###
 */

 /**************************************************************************
 *  _ILSimpleGetText
 *
 * gets the text for the first item in the pidl (eg. simple pidl)
 *
 * returns the length of the string
 */
DWORD _ILSimpleGetText (LPCITEMIDLIST pidl, LPSTR szOut, UINT uOutSize)
{
	DWORD		dwReturn=0;
	LPSTR		szSrc;
	GUID const * 	riid;
	char szTemp[MAX_PATH];

	TRACE("(%p %p %x)\n",pidl,szOut,uOutSize);

	if (!pidl) return 0;

	if (szOut)
	  *szOut = 0;

	if (_ILIsDesktop(pidl))
	{
	 /* desktop */
	  if (HCR_GetClassNameA(&CLSID_ShellDesktop, szTemp, MAX_PATH))
	  {
	    if (szOut)
	      lstrcpynA(szOut, szTemp, uOutSize);

	    dwReturn = strlen (szTemp);
	  }
	}
	else if (( szSrc = _ILGetTextPointer(pidl) ))
	{
	  /* filesystem */
	  if (szOut)
	    lstrcpynA(szOut, szSrc, uOutSize);

	  dwReturn = strlen(szSrc);
	}
	else if (( riid = _ILGetGUIDPointer(pidl) ))
	{
	  /* special folder */
	  if ( HCR_GetClassNameA(riid, szTemp, MAX_PATH) )
	  {
	    if (szOut)
	      lstrcpynA(szOut, szTemp, uOutSize);

	    dwReturn = strlen (szTemp);
	  }
	}
	else
	{
	  ERR("-- no text\n");
	}

	TRACE("-- (%p=%s 0x%08lx)\n",szOut,debugstr_a(szOut),dwReturn);
	return dwReturn;
}

 /**************************************************************************
 *  _ILSimpleGetTextW
 *
 * gets the text for the first item in the pidl (eg. simple pidl)
 *
 * returns the length of the string
 */
DWORD _ILSimpleGetTextW (LPCITEMIDLIST pidl, LPWSTR szOut, UINT uOutSize)
{
	DWORD	dwReturn;
	char	szTemp[MAX_PATH];

	TRACE("(%p %p %x)\n",pidl,szOut,uOutSize);

	dwReturn = _ILSimpleGetText(pidl, szTemp, uOutSize);

	if (!MultiByteToWideChar(CP_ACP, 0, szTemp, -1, szOut, MAX_PATH))
		*szOut = 0;

	TRACE("-- (%p=%s 0x%08lx)\n",szOut,debugstr_w(szOut),dwReturn);
	return dwReturn;
}

/**************************************************************************
 *
 *	### 4. getting pointers to parts of pidls ###
 *
 **************************************************************************
 *  _ILGetDataPointer()
 */
LPPIDLDATA _ILGetDataPointer(LPCITEMIDLIST pidl)
{
	if(pidl && pidl->mkid.cb != 0x00)
	  return (LPPIDLDATA) &(pidl->mkid.abID);
	return NULL;
}

/**************************************************************************
 *  _ILGetTextPointer()
 * gets a pointer to the long filename string stored in the pidl
 */
LPSTR _ILGetTextPointer(LPCITEMIDLIST pidl)
{/*	TRACE(pidl,"(pidl%p)\n", pidl);*/

	LPPIDLDATA pdata = _ILGetDataPointer(pidl);

	if (pdata)
	{
	  switch (pdata->type)
	  {
	    case PT_GUID:
	    case PT_SHELLEXT:
	      return NULL;

	    case PT_DRIVE:
	    case PT_DRIVE1:
	    case PT_DRIVE2:
	    case PT_DRIVE3:
	      return (LPSTR)&(pdata->u.drive.szDriveName);

	    case PT_FOLDER:
	    case PT_FOLDER1:
	    case PT_VALUE:
	    case PT_IESPECIAL1:
	    case PT_RAS_FOLDER:
	    case PT_IESPECIAL2:
	      return (LPSTR)&(pdata->u.file.szNames);

	    case PT_WORKGRP:
	    case PT_COMP:
	    case PT_NETWORK:
	    case PT_NETPROVIDER:
	    case PT_SHARE:
	      return (LPSTR)&(pdata->u.network.szNames);
	  }
	}
	return NULL;
}

/**************************************************************************
 *  _ILGetSTextPointer()
 * gets a pointer to the short filename string stored in the pidl
 */
LPSTR _ILGetSTextPointer(LPCITEMIDLIST pidl)
{/*	TRACE(pidl,"(pidl%p)\n", pidl);*/

	LPPIDLDATA pdata =_ILGetDataPointer(pidl);

	if (pdata)
	{
	  switch (pdata->type)
	  {
	    case PT_FOLDER:
	    case PT_VALUE:
	    case PT_IESPECIAL1:
	    case PT_RAS_FOLDER:
	    case PT_IESPECIAL2:
	      return (LPSTR)(pdata->u.file.szNames + strlen (pdata->u.file.szNames) + 1);

	    case PT_WORKGRP:
	      return (LPSTR)(pdata->u.network.szNames + strlen (pdata->u.network.szNames) + 1);
	  }
	}
	return NULL;
}

/**************************************************************************
 * _ILGetGUIDPointer()
 *
 * returns reference to guid stored in some pidls
 */
REFIID _ILGetGUIDPointer(LPCITEMIDLIST pidl)
{
	LPPIDLDATA pdata =_ILGetDataPointer(pidl);

	TRACE("%p\n", pidl);

	if (pdata)
	{
	  TRACE("pdata->type 0x%04x\n", pdata->type);
	  switch (pdata->type)
	  {
	    case PT_SHELLEXT:
	    case PT_GUID:
	      return (REFIID) &(pdata->u.guid.guid);

	    default:
		TRACE("Unknown pidl type 0x%04x\n", pdata->type);
		break;
	  }
	}
	return NULL;
}

/*************************************************************************
 * _ILGetFileDateTime
 *
 * Given the ItemIdList, get the FileTime
 *
 * PARAMS
 *      pidl        [I] The ItemIDList
 *      pFt         [I] the resulted FILETIME of the file
 *
 * RETURNS
 *     True if Successful
 *
 * NOTES
 *
 */
BOOL _ILGetFileDateTime(LPCITEMIDLIST pidl, FILETIME *pFt)
{
    LPPIDLDATA pdata = _ILGetDataPointer(pidl);

    if(! pdata) return FALSE;

    switch (pdata->type)
    {
        case PT_FOLDER:
        case PT_VALUE:
            DosDateTimeToFileTime(pdata->u.file.uFileDate, pdata->u.file.uFileTime, pFt);
            break;
        default:
            return FALSE;
    }
    return TRUE;
}

BOOL _ILGetFileDate (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
{
	FILETIME ft,lft;
	SYSTEMTIME time;
	BOOL ret;

	if (_ILGetFileDateTime( pidl, &ft )) {
	    FileTimeToLocalFileTime(&ft, &lft);
	    FileTimeToSystemTime (&lft, &time);
	    ret = GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&time, NULL,  pOut, uOutSize);
	} else {
	    pOut[0] = '\0';
	    ret = FALSE;
	}
	return ret;

}

/*************************************************************************
 * _ILGetFileSize
 *
 * Given the ItemIdList, get the FileSize
 *
 * PARAMS
 *      pidl    [I] The ItemIDList
 *	pOut	[I] The buffer to save the result
 *      uOutsize [I] The size of the buffer
 *
 * RETURNS
 *     The FileSize
 *
 * NOTES
 *	pOut can be null when no string is needed
 *
 */
DWORD _ILGetFileSize (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
{
	LPPIDLDATA pdata = _ILGetDataPointer(pidl);
	DWORD dwSize;

	if(! pdata) return 0;

	switch (pdata->type)
	{
	  case PT_VALUE:
	    dwSize = pdata->u.file.dwFileSize;
	    if (pOut) StrFormatByteSizeA(dwSize, pOut, uOutSize);
	    return dwSize;
	}
	if (pOut) *pOut = 0x00;
	return 0;
}

BOOL _ILGetExtension (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
{
	char szTemp[MAX_PATH];
	const char * pPoint;
	LPCITEMIDLIST  pidlTemp=pidl;

	TRACE("pidl=%p\n",pidl);

	if (!pidl) return FALSE;

	pidlTemp = ILFindLastID(pidl);

	if (!_ILIsValue(pidlTemp)) return FALSE;
	if (!_ILSimpleGetText(pidlTemp, szTemp, MAX_PATH)) return FALSE;

	pPoint = PathFindExtensionA(szTemp);

	if (! *pPoint) return FALSE;

	pPoint++;
	lstrcpynA(pOut, pPoint, uOutSize);
	TRACE("%s\n",pOut);

	return TRUE;
}

/*************************************************************************
 * _ILGetFileType
 *
 * Given the ItemIdList, get the file type description
 *
 * PARAMS
 *      pidl        [I] The ItemIDList (simple)
 *      pOut        [I] The buffer to save the result
 *      uOutsize    [I] The size of the buffer
 *
 * RETURNS
 *	nothing
 *
 * NOTES
 *	This function copies as much as possible into the buffer.
 */
void _ILGetFileType(LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
{
	if(_ILIsValue(pidl))
	{
	  char sTemp[64];
          if(uOutSize > 0)
          {
            pOut[0] = 0;
          }
	  if (_ILGetExtension (pidl, sTemp, 64))
	  {
	    if (!( HCR_MapTypeToValueA(sTemp, sTemp, 64, TRUE)
	        && HCR_MapTypeToValueA(sTemp, pOut, uOutSize, FALSE )))
	    {
	      lstrcpynA (pOut, sTemp, uOutSize - 6);
	      strcat (pOut, "-file");
	    }
	  }
	}
	else
	{
	  lstrcpynA(pOut, "Folder", uOutSize);
	}
}

/*************************************************************************
 * _ILGetFileAttributes
 *
 * Given the ItemIdList, get the Attrib string format
 *
 * PARAMS
 *      pidl        [I] The ItemIDList
 *      pOut        [I] The buffer to save the result
 *      uOutsize    [I] The size of the Buffer
 *
 * RETURNS
 *     Attributes
 *
 * FIXME
 *  return value 0 in case of error is a valid return value
 *
 */
DWORD _ILGetFileAttributes(LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
{
	LPPIDLDATA pData = _ILGetDataPointer(pidl);
	WORD wAttrib = 0;
	int i;

	if(! pData) return 0;

	switch(pData->type)
	{
	  case PT_FOLDER:
	  case PT_VALUE:
	    wAttrib = pData->u.file.uFileAttribs;
	    break;
	}

	if(uOutSize >= 6)
	{
	  i=0;
	  if(wAttrib & FILE_ATTRIBUTE_READONLY)
	  {
	    pOut[i++] = 'R';
	  }
	  if(wAttrib & FILE_ATTRIBUTE_HIDDEN)
	  {
	    pOut[i++] = 'H';
	  }
	  if(wAttrib & FILE_ATTRIBUTE_SYSTEM)
	  {
	    pOut[i++] = 'S';
	  }
	  if(wAttrib & FILE_ATTRIBUTE_ARCHIVE)
	  {
	    pOut[i++] = 'A';
	  }
	  if(wAttrib & FILE_ATTRIBUTE_COMPRESSED)
	  {
	    pOut[i++] = 'C';
	  }
	  pOut[i] = 0x00;
	}
	return wAttrib;
}

/*************************************************************************
* ILFreeaPidl
*
* free a aPidl struct
*/
void _ILFreeaPidl(LPITEMIDLIST * apidl, UINT cidl)
{
	UINT   i;

	if (apidl)
	{
	  for (i = 0; i < cidl; i++) SHFree(apidl[i]);
	  SHFree(apidl);
	}
}

/*************************************************************************
* ILCopyaPidl
*
* copies an aPidl struct
*/
LPITEMIDLIST* _ILCopyaPidl(LPCITEMIDLIST * apidlsrc, UINT cidl)
{
	UINT i;
	LPITEMIDLIST * apidldest = (LPITEMIDLIST*)SHAlloc(cidl * sizeof(LPITEMIDLIST));
	if(!apidlsrc) return NULL;

	for (i = 0; i < cidl; i++)
	  apidldest[i] = ILClone(apidlsrc[i]);

	return apidldest;
}

/*************************************************************************
* _ILCopyCidaToaPidl
*
* creates aPidl from CIDA
*/
LPITEMIDLIST* _ILCopyCidaToaPidl(LPITEMIDLIST* pidl, LPIDA cida)
{
	UINT i;
	LPITEMIDLIST * dst = (LPITEMIDLIST*)SHAlloc(cida->cidl * sizeof(LPITEMIDLIST));

	if(!dst) return NULL;

	if (pidl)
	  *pidl = ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[0]]));

	for (i = 0; i < cida->cidl; i++)
	  dst[i] = ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[i + 1]]));

	return dst;
}
