/*
 *    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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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 COBJMACROS
#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 "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 (!*(const WORD*)pidl || type == ILGDN_FORPARSING)
        {
            ret = IShellFolder_GetDisplayNameOf(lsf, pidl, flag, &strret);
            if (SUCCEEDED(ret))
            {
                if(!StrRetToStrNW(path, MAX_PATH, &strret, pidl))
                    ret = E_FAIL;
            }
        }
        else
        {
            ret = SHBindToParent(pidl, &IID_IShellFolder, (LPVOID*)&psfParent, &pidllast);
            if (SUCCEEDED(ret))
            {
                ret = IShellFolder_GetDisplayNameOf(psfParent, pidllast, flag, &strret);
                if (SUCCEEDED(ret))
                {
                    if(!StrRetToStrNW(path, MAX_PATH, &strret, pidllast))
                        ret = E_FAIL;
                }
                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)
{
    WCHAR lpszDisplayName[MAX_PATH];

    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;

    return SHILCreateFromPathW(lpszDisplayName, ppidl, attributes);
}

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 ))
            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 ))
            return FALSE;

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

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

    /* not immediate descent */
    if ( ILGetNext(pChild)->mkid.cb && bImmediate)
        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;

    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  = (LPCSHITEMID)(((const BYTE*)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 = (LPCITEMIDLIST) (((const BYTE*)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]
 *
 * RETURNS
 *  Nothing
 *
 * 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]
 *
 * RETURNS
 *  Nothing
 *
 * NOTES
 *  exported by ordinal.
 */
void WINAPI ILGlobalFree( LPITEMIDLIST pidl)
{
    TRACE("%p\n", pidl);

    if (pidl)
        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]
 *
 * See ILCreateFromPathA.
 */
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 nonexistent 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 nonexistent 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);

    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)
{
    LPSTR filename, shortname;
    WIN32_FIND_DATAA * pfd;

    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:
        pfd = dest;

        if (_ILIsDrive(pidl) || _ILIsSpecialFolder(pidl))
            return E_INVALIDARG;

        if (len < 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)
{
    LPSTR filename, shortname;
    WIN32_FIND_DATAW * pfd = dest;

    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:
        pfd = dest;

        if (_ILIsDrive(pidl))
            return E_INVALIDARG;

        if (len < 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;
}

/*************************************************************************
 * 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)
{
    WCHAR wszPath[MAX_PATH];
    BOOL bSuccess;

    bSuccess = SHGetPathFromIDListW(pidl, wszPath);
    if (bSuccess) 
        WideCharToMultiByte(CP_ACP, 0, wszPath, -1, pszPath, MAX_PATH, NULL, NULL);

    return bSuccess;
}

/*************************************************************************
 * SHGetPathFromIDListW             [SHELL32.@]
 *
 * See SHGetPathFromIDListA.
 */
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
{
    HRESULT hr;
    LPCITEMIDLIST pidlLast;
    LPSHELLFOLDER psfFolder;
    DWORD dwAttributes;
    STRRET strret;

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

    if (!pidl)
        return FALSE;

    hr = SHBindToParent(pidl, &IID_IShellFolder, (VOID**)&psfFolder, &pidlLast);
    if (FAILED(hr)) return FALSE;

    dwAttributes = SFGAO_FILESYSTEM;
    hr = IShellFolder_GetAttributesOf(psfFolder, 1, &pidlLast, &dwAttributes);
    if (FAILED(hr) || !(dwAttributes & SFGAO_FILESYSTEM)) {
        IShellFolder_Release(psfFolder);
        return FALSE;
    }
                
    hr = IShellFolder_GetDisplayNameOf(psfFolder, pidlLast, SHGDN_FORPARSING, &strret);
    IShellFolder_Release(psfFolder);
    if (FAILED(hr)) return FALSE;

    hr = StrRetToBufW(&strret, pidlLast, pszPath, MAX_PATH);

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

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

    TRACE_(shell)("pidl=%p\n", pidl);
    pdump(pidl);
    
    if (!pidl || !ppv)
        return E_INVALIDARG;
    
    *ppv = NULL;
    if (ppidlLast)
        *ppidlLast = NULL;

    hr = SHGetDesktopFolder(&psfDesktop);
    if (FAILED(hr))
        return hr;

    if (_ILIsPidlSimple(pidl))
    {
        /* we are on desktop level */
        hr = IShellFolder_QueryInterface(psfDesktop, riid, ppv);
    }
    else
    {
        LPITEMIDLIST pidlParent = ILClone(pidl);
        ILRemoveLastID(pidlParent);
        hr = IShellFolder_BindToObject(psfDesktop, pidlParent, NULL, riid, ppv);
        SHFree (pidlParent);
    }

    IShellFolder_Release(psfDesktop);

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

    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, unsigned int size)
{
    LPITEMIDLIST pidlOut = NULL;

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

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

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

        pidlNext = ILGetNext(pidlOut);
        if (pidlNext)
            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 _ILCreateMyDocuments()
{
    TRACE("()\n");
    return _ILCreateGuid(PT_GUID, &CLSID_MyDocuments);
}

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_SHELLEXT, &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_YAGUID, &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 || type == PT_YAGUID)
    {
        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 _ILCreateGuidFromStrW(LPCWSTR szGUID)
{
    IID iid;

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

LPITEMIDLIST _ILCreateFromFindDataW( WIN32_FIND_DATAW *wfd )
{
    /* FIXME: should make unicode PIDLs */
    WIN32_FIND_DATAA fda;

    memset( &fda, 0, sizeof fda );
    fda.dwFileAttributes = wfd->dwFileAttributes;
    fda.ftCreationTime = wfd->ftCreationTime;
    fda.ftLastAccessTime = wfd->ftLastAccessTime;
    fda.ftLastWriteTime = wfd->ftLastWriteTime;
    fda.nFileSizeHigh = wfd->nFileSizeHigh;
    fda.nFileSizeLow = wfd->nFileSizeLow;
    fda.dwReserved0 = wfd->dwReserved0;
    fda.dwReserved1 = wfd->dwReserved1;
    WideCharToMultiByte( CP_ACP, 0, wfd->cFileName, -1,
                         fda.cFileName, MAX_PATH, NULL, NULL );
    return _ILCreateFromFindDataA( &fda );
}

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
     */
    pidl = _ILAlloc(type, sizeof(FileStruct) + (len - 1) + len1);
    if (pidl)
    {
        LPPIDLDATA pData;
        LPSTR pszDest;

        /* set attributes */
        pData = _ILGetDataPointer(pidl);
        if (pData)
        {
            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;
        }
        pszDest = _ILGetTextPointer(pidl);
        if (pszDest)
        {
            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;
}

HRESULT _ILCreateFromPathW(LPCWSTR szPath, LPITEMIDLIST* ppidl)
{
    HANDLE hFile;
    WIN32_FIND_DATAW stffile;

    if (!ppidl)
        return E_INVALIDARG;

    hFile = FindFirstFileW(szPath, &stffile);
    if (hFile == INVALID_HANDLE_VALUE)
        return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);

    FindClose(hFile);

    *ppidl = _ILCreateFromFindDataW(&stffile);

    return *ppidl ? S_OK : E_OUTOFMEMORY;
}

LPITEMIDLIST _ILCreateDrive(LPCWSTR lpszNew)
{
    LPITEMIDLIST pidlOut;

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

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

        pszDest = _ILGetTextPointer(pidlOut);
        if (pszDest)
        {
            strcpy(pszDest, "x:\\");
            pszDest[0]=toupperW(lpszNew[0]);
            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 || PT_YAGUID == 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) (((const BYTE*)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];
    FileStructW *pFileStructW = _ILGetFileStructW(pidl);

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

    if (pFileStructW) {
        lstrcpynW(szOut, pFileStructW->wszName, uOutSize);
        dwReturn = lstrlenW(pFileStructW->wszName);
    } else {
        dwReturn = _ILSimpleGetText(pidl, szTemp, MAX_PATH);

        if (!MultiByteToWideChar(CP_ACP, 0, szTemp, -1, szOut, uOutSize))
            *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)
        return NULL;

    switch (pdata->type)
    {
    case PT_GUID:
    case PT_SHELLEXT:
    case PT_YAGUID:
        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_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)
        return NULL;

    switch (pdata->type)
    {
    case PT_FOLDER:
    case PT_VALUE:
    case PT_IESPECIAL1:
    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
 */
IID* _ILGetGUIDPointer(LPCITEMIDLIST pidl)
{
    LPPIDLDATA pdata =_ILGetDataPointer(pidl);

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

    if (!pdata)
        return NULL;

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

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

/******************************************************************************
 * _ILGetFileStructW [Internal]
 *
 * Get pointer the a SHITEMID's FileStructW field if present
 *
 * PARAMS
 *  pidl [I] The SHITEMID
 *
 * RETURNS
 *  Success: Pointer to pidl's FileStructW field.
 *  Failure: NULL
 */
FileStructW* _ILGetFileStructW(LPCITEMIDLIST pidl) {
    FileStructW *pFileStructW;
    WORD cbOffset;
    
    if (!(_ILIsValue(pidl) || _ILIsFolder(pidl)))
        return NULL;

    cbOffset = *(WORD*)((LPBYTE)pidl + pidl->mkid.cb - sizeof(WORD));
    pFileStructW = (FileStructW*)((LPBYTE)pidl + cbOffset);

    /* Currently I don't see a fool prove way to figure out if a pidl is for sure of WinXP
     * style with a FileStructW member. If we switch all our shellfolder-implementations to
     * the new format, this won't be a problem. For now, we do as many sanity checks as possible. */
    if (cbOffset & 0x1 || /* FileStructW member is word aligned in the pidl */
        /* FileStructW is positioned after FileStruct */
        cbOffset < sizeof(pidl->mkid.cb) + sizeof(PIDLTYPE) + sizeof(FileStruct) ||
        /* There has to be enough space at cbOffset in the pidl to hold FileStructW and cbOffset */
        cbOffset > pidl->mkid.cb - sizeof(cbOffset) - sizeof(FileStructW) ||
        pidl->mkid.cb != cbOffset + pFileStructW->cbLen)
    {
        WARN("Invalid pidl format (cbOffset = %d)!\n", cbOffset);
        return NULL;
    }

    return pFileStructW;
}

/*************************************************************************
 * _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);
        if (ret) 
        {
            /* Append space + time without seconds */
            pOut[ret-1] = ' ';
            GetTimeFormatA(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &time, NULL, &pOut[ret], uOutSize - ret);
        }
    }
    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;

    apidldest = 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;

    dst = 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;
}
