/*
 *	Shell Folder stuff (...and all the OLE-Objects of SHELL32.DLL)
 *
 *	Copyright 1997	Marcus Meissner
 *	Copyright 1998	Juergen Schmied
 *
 *  !!! currently work in progress on all classes !!!
 *  <contact juergen.schmied@metronet.de, 980624>
 */

#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "ole.h"
#include "ole2.h"
#include "debug.h"
#include "compobj.h"
#include "interfaces.h"
#include "shlobj.h"
#include "winerror.h"
#include "winnls.h"

/* FIXME should be moved to a header file. IsEqualGUID 
is declared but not exported in compobj.c !!!*/
#define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID)))
#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2)
#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2)
/***************************************************************************
 *  GetNextElement (internal function)
 *
 *  RETURNS
 *    LPSTR pointer to first, not yet parsed char
 */
LPSTR GetNextElement(
    LPSTR pszNext, /*[IN] string to get the element from*/
		LPSTR pszOut,  /*[IN] pointer to buffer whitch receives string*/
		DWORD dwOut)   /*[IN] length of pszOut*/
{ LPSTR   pszTail = pszNext;
  DWORD dwCopy;
  TRACE(shell,"(%s %p 0x%08lx)\n",pszNext,	pszOut, dwOut);

  if(!pszNext || !*pszNext)
    return NULL;

  while(*pszTail && (*pszTail != '\\'))
  { pszTail++;
  }
  dwCopy=((LPBYTE)pszTail-(LPBYTE)pszNext)/sizeof(CHAR)+1;
  lstrcpyn32A(pszOut, pszNext, (dwOut<dwCopy)? dwOut : dwCopy);

  if(*pszTail)
  {  pszTail++;
	}

  TRACE(shell,"--(%s %s 0x%08lx)\n",pszNext,	pszOut, dwOut);
  return pszTail;
}

/**************************************************************************
*  IClassFactory Implementation
*/
static HRESULT WINAPI IClassFactory_QueryInterface(LPCLASSFACTORY,REFIID,LPVOID*);
static ULONG WINAPI IClassFactory_AddRef(LPCLASSFACTORY);
static ULONG WINAPI IClassFactory_Release(LPCLASSFACTORY);
static HRESULT WINAPI IClassFactory_CreateInstance();
/*static HRESULT WINAPI IClassFactory_LockServer();*/
/**************************************************************************
 *  IClassFactory_VTable
 */
static IClassFactory_VTable clfvt = {
	IClassFactory_QueryInterface,
	IClassFactory_AddRef,
	IClassFactory_Release,
	IClassFactory_CreateInstance,
/*	IClassFactory_LockServer*/
};

/**************************************************************************
 *  IClassFactory_Constructor
 */

LPCLASSFACTORY IClassFactory_Constructor()
{	LPCLASSFACTORY	lpclf;

	lpclf= (LPCLASSFACTORY)HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactory));
	lpclf->ref = 1;
	lpclf->lpvtbl = &clfvt;
  TRACE(shell,"(%p)->()\n",lpclf);
	return lpclf;
}
/**************************************************************************
 *  IClassFactory::QueryInterface
 */
static HRESULT WINAPI IClassFactory_QueryInterface(
  LPCLASSFACTORY this, REFIID riid, LPVOID *ppvObj)
{  char	xriid[50];
   WINE_StringFromCLSID((LPCLSID)riid,xriid);
   TRACE(shell,"(%p)->(\n\tIID:\t%s)\n",this,xriid);

  *ppvObj = NULL;

  if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
  { *ppvObj = this; 
  }
  else if(IsEqualIID(riid, &IID_IClassFactory))  /*IClassFactory*/
  {    *ppvObj = (IClassFactory*)this;
  }   

  if(*ppvObj)
  { (*(LPCLASSFACTORY*)ppvObj)->lpvtbl->fnAddRef(this);  	
    TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
    return S_OK;
  }
	TRACE(shell,"-- Interface: E_NOINTERFACE\n");
  return E_NOINTERFACE;
}  
/******************************************************************************
 * IClassFactory_AddRef
 */
static ULONG WINAPI IClassFactory_AddRef(LPCLASSFACTORY this)
{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
	return ++(this->ref);
}
/******************************************************************************
 * IClassFactory_Release
 */
static ULONG WINAPI IClassFactory_Release(LPCLASSFACTORY this)
{	TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
	if (!--(this->ref)) 
	{ TRACE(shell,"-- destroying IClassFactory(%p)\n",this);
		HeapFree(GetProcessHeap(),0,this);
		return 0;
	}
	return this->ref;
}
/******************************************************************************
 * IClassFactory_CreateInstance
 */
static HRESULT WINAPI IClassFactory_CreateInstance(
  LPCLASSFACTORY this, LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject)
{ IUnknown *pObj = NULL;
	HRESULT hres;
	char	xriid[50];

  WINE_StringFromCLSID((LPCLSID)riid,xriid);
  TRACE(shell,"%p->(%p,\n\tIID:\t%s)\n",this,pUnknown,xriid);

	*ppObject = NULL;
		
	if(pUnknown)
	{	return(CLASS_E_NOAGGREGATION);
	}

	if (IsEqualIID(riid, &IID_IShellFolder))
  { pObj = (IUnknown *)IShellFolder_Constructor(NULL,NULL);
  } 
	else
	{ ERR(shell,"unknown IID requested\n\tIID:\t%s\n",xriid);
	  return(E_NOINTERFACE);
	}
	
  if (!pObj)
  { return(E_OUTOFMEMORY);
  }
	 
	hres = pObj->lpvtbl->fnQueryInterface(pObj,riid, ppObject);
  pObj->lpvtbl->fnRelease(pObj);
  TRACE(shell,"-- Object created: (%p)->%p\n",this,*ppObject);

  return hres;
}
/******************************************************************************
 * IClassFactory_LockServer
 */
/*static HRESULT WINAPI IClassFactory_LockServer(LPCLASSFACTORY this, BOOL)
{ TRACE(shell,"%p->(), not implemented\n",this)
  return E_NOTIMPL;
}

*/
/**************************************************************************
 *  IEnumIDList Implementation
 */
static HRESULT WINAPI IEnumIDList_QueryInterface(LPENUMIDLIST,REFIID,LPVOID*);
static ULONG WINAPI IEnumIDList_AddRef(LPENUMIDLIST);
static ULONG WINAPI IEnumIDList_Release(LPENUMIDLIST);
static HRESULT WINAPI IEnumIDList_Next(LPENUMIDLIST,ULONG,LPITEMIDLIST*,ULONG*);
static HRESULT WINAPI IEnumIDList_Skip(LPENUMIDLIST,ULONG);
static HRESULT WINAPI IEnumIDList_Reset(LPENUMIDLIST);
static HRESULT WINAPI IEnumIDList_Clone(LPENUMIDLIST,LPENUMIDLIST*);
static BOOL32 WINAPI IEnumIDList_CreateEnumList(LPENUMIDLIST,LPCSTR, DWORD);
static BOOL32 WINAPI IEnumIDList_AddToEnumList(LPENUMIDLIST,LPITEMIDLIST);
static BOOL32 WINAPI IEnumIDList_DeleteList(LPENUMIDLIST);
/**************************************************************************
 *  IEnumIDList_VTable
 */
static IEnumIDList_VTable eidlvt = {
	IEnumIDList_QueryInterface,
	IEnumIDList_AddRef,
	IEnumIDList_Release,
	IEnumIDList_Next,
	IEnumIDList_Skip,
	IEnumIDList_Reset,
  IEnumIDList_Clone,
	IEnumIDList_CreateEnumList,
  IEnumIDList_AddToEnumList,
	IEnumIDList_DeleteList
};

/**************************************************************************
 *  IEnumIDList_Constructor
 */

LPENUMIDLIST IEnumIDList_Constructor( LPCSTR lpszPath, DWORD dwFlags, HRESULT* pResult)
{	LPENUMIDLIST	lpeidl;

	lpeidl = (LPENUMIDLIST)HeapAlloc(GetProcessHeap(),0,sizeof(IEnumIDList));
	lpeidl->ref = 1;
	lpeidl->lpvtbl = &eidlvt;
	lpeidl->mpFirst=NULL;
	lpeidl->mpLast=NULL;
	lpeidl->mpCurrent=NULL;

  TRACE(shell,"(%p)->(%s 0x%08lx %p)\n",lpeidl,lpszPath,dwFlags,pResult);

	lpeidl->mpPidlMgr=PidlMgr_Constructor();
  if (!lpeidl->mpPidlMgr)
	{ if (pResult)
	  { *pResult=E_OUTOFMEMORY;
			HeapFree(GetProcessHeap(),0,lpeidl);
			return NULL;
		}
	}

	if(!IEnumIDList_CreateEnumList(lpeidl, lpszPath, dwFlags))
  { if(pResult)
    { *pResult = E_OUTOFMEMORY;
			HeapFree(GetProcessHeap(),0,lpeidl->mpPidlMgr);
			HeapFree(GetProcessHeap(),0,lpeidl);
			return NULL;
		}
  }

  TRACE(shell,"-- (%p)->()\n",lpeidl);
	return lpeidl;
}

/**************************************************************************
 *  EnumIDList::QueryInterface
 */
static HRESULT WINAPI IEnumIDList_QueryInterface(
  LPENUMIDLIST this, REFIID riid, LPVOID *ppvObj)
{  char	xriid[50];
   WINE_StringFromCLSID((LPCLSID)riid,xriid);
   TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);

  *ppvObj = NULL;

  if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
  { *ppvObj = this; 
  }
  else if(IsEqualIID(riid, &IID_IEnumIDList))  /*IEnumIDList*/
  {    *ppvObj = (IEnumIDList*)this;
  }   

  if(*ppvObj)
  { (*(LPENUMIDLIST*)ppvObj)->lpvtbl->fnAddRef(this);  	
    TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
    return S_OK;
  }
	TRACE(shell,"-- Interface: E_NOINTERFACE\n");
	return E_NOINTERFACE;
}   

/******************************************************************************
 * IEnumIDList_AddRef
 */
static ULONG WINAPI IEnumIDList_AddRef(LPENUMIDLIST this)
{ TRACE(shell,"(%p)->()\n",this);
	return ++(this->ref);
}
/******************************************************************************
 * IEnumIDList_Release
 */
static ULONG WINAPI IEnumIDList_Release(LPENUMIDLIST this)
{	TRACE(shell,"(%p)->()\n",this);
	if (!--(this->ref)) 
	{ TRACE(shell," destroying IEnumIDList(%p)\n",this);
		HeapFree(GetProcessHeap(),0,this);
		return 0;
	}
	return this->ref;
}
   
/**************************************************************************
 *  IEnumIDList_Next
 */

static HRESULT WINAPI IEnumIDList_Next(
	LPENUMIDLIST this,ULONG celt,LPITEMIDLIST * rgelt,ULONG *pceltFetched) 
{ ULONG    i;
  HRESULT  hr = S_OK;

  LPITEMIDLIST  temp;

	TRACE(shell,"(%p)->(%ld,%p, %p)\n",this,celt,rgelt,pceltFetched);

	*rgelt=0;
	
  if(celt > 1 && !pceltFetched)
  { return E_INVALIDARG;
	}

  for(i = 0; i < celt; i++)
  { if(!(this->mpCurrent))
    { hr =  S_FALSE;
      break;
    }
		temp = this->mpPidlMgr->lpvtbl->fnCopy(this->mpPidlMgr, this->mpCurrent->pidl);
    rgelt[i] = temp;
    this->mpCurrent = this->mpCurrent->pNext;
  }
  if(pceltFetched)
  {  *pceltFetched = i;
	}

  return hr;
}

/**************************************************************************
*  IEnumIDList_Skip
*/
static HRESULT WINAPI IEnumIDList_Skip(
	LPENUMIDLIST this,ULONG celt)
{ DWORD    dwIndex;
  HRESULT  hr = S_OK;

  TRACE(shell,"(%p)->(%lu)\n",this,celt);

  for(dwIndex = 0; dwIndex < celt; dwIndex++)
  { if(!this->mpCurrent)
    { hr = S_FALSE;
      break;
    }
    this->mpCurrent = this->mpCurrent->pNext;
  }
  return hr;
}
/**************************************************************************
*  IEnumIDList_Reset
*/
static HRESULT WINAPI IEnumIDList_Reset(LPENUMIDLIST this)
{ TRACE(shell,"(%p)\n",this);
  this->mpCurrent = this->mpFirst;
  return S_OK;
}
/**************************************************************************
*  IEnumIDList_Clone
*/
static HRESULT WINAPI IEnumIDList_Clone(
	LPENUMIDLIST this,LPENUMIDLIST * ppenum)
{ TRACE(shell,"(%p)->() to (%p)->() E_NOTIMPL\n",this,ppenum);
	return E_NOTIMPL;
}
/**************************************************************************
 *  EnumIDList_CreateEnumList()
 *  fixme: devices not handled
 *  fixme: add wildcards to path
 */
static BOOL32 WINAPI IEnumIDList_CreateEnumList(LPENUMIDLIST this, LPCSTR lpszPath, DWORD dwFlags)
{ LPITEMIDLIST   pidl=NULL;
  WIN32_FIND_DATA32A stffile;	
  HANDLE32 hFile;
	
  TRACE(shell,"(%p)->(%s 0x%08lx) \n",this,lpszPath,dwFlags);

  /*enumerate the folders*/
  if(dwFlags & SHCONTF_FOLDERS)
  {	/* special case - we can't enumerate the Desktop level Objects (MyComputer,Nethood...
    so we need to fake an enumeration of those.*/
	  if(!lpszPath)
    { TRACE (shell,"(%p)-> enumerate the special-folder items\n",this);
  		//create the pidl for this item
      pidl = this->mpPidlMgr->lpvtbl->fnCreateDesktop(this->mpPidlMgr);
      if(pidl)
      { if(!IEnumIDList_AddToEnumList(this, pidl))
          return FALSE;
      }
      else
      { return FALSE;
      }
     }   
     else
     { TRACE (shell,"(%p)-> enumerate the folder items for %s\n",this,lpszPath);
		   hFile = FindFirstFile32A(lpszPath,&stffile);
       do
       { if (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
         //create the pidl for this item
         /* fixme: the shortname should be given too*/
         pidl = this->mpPidlMgr->lpvtbl->fnCreateFolder(this->mpPidlMgr, stffile.cFileName);
         if(pidl)
         { if(!IEnumIDList_AddToEnumList(this, pidl))
             return FALSE;
         }
         else
         { return FALSE;
         }   
      } while( FindNextFile32A(hFile,&stffile));
			FindClose32 (hFile);
    }
  }   
  //enumerate the non-folder items (values)
  if(dwFlags & SHCONTF_NONFOLDERS)
  { TRACE (shell,"(%p)-> enumerate the non-folder items (values) of %s\n",this,lpszPath);
	  hFile = FindFirstFile32A(lpszPath,&stffile);
    do
    { if (! (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
		  //create the pidl for this item
			/* fixme: the shortname should be given too*/
      pidl = this->mpPidlMgr->lpvtbl->fnCreateFolder(this->mpPidlMgr, stffile.cFileName);
      if(pidl)
      { if(!IEnumIDList_AddToEnumList(this, pidl))
        { return FALSE;
			  }
      }
      else
      { return FALSE;
      }   
    } while( FindNextFile32A(hFile,&stffile));
	  FindClose32 (hFile);
  } 
  return TRUE;
}

/**************************************************************************
 *  EnumIDList_AddToEnumList()
 */
static BOOL32 WINAPI IEnumIDList_AddToEnumList(LPENUMIDLIST this,LPITEMIDLIST pidl)
{ LPENUMLIST  pNew;

  TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl);
  pNew = (LPENUMLIST)HeapAlloc(GetProcessHeap(),0,sizeof(ENUMLIST));
  if(pNew)
  { //set the next pointer
    pNew->pNext = NULL;
    pNew->pidl = pidl;

    //is this the first item in the list?
    if(!this->mpFirst)
    { this->mpFirst = pNew;
      this->mpCurrent = pNew;
    }
   
    if(this->mpLast)
    { //add the new item to the end of the list
      this->mpLast->pNext = pNew;
    }
   
    //update the last item pointer
    this->mpLast = pNew;
		TRACE(shell,"(%p)->(first=%p, last=%p)\n",this,this->mpFirst,this->mpLast);
    return TRUE;
  }
  return FALSE;
}
/**************************************************************************
*   EnumIDList_DeleteList()
*/
static BOOL32 WINAPI IEnumIDList_DeleteList(LPENUMIDLIST this)
{ LPENUMLIST  pDelete;

  TRACE(shell,"(%p)->()\n",this);
	
  while(this->mpFirst)
  { pDelete = this->mpFirst;
    this->mpFirst = pDelete->pNext;

    //free the pidl
    this->mpPidlMgr->lpvtbl->fnDelete(this->mpPidlMgr,pDelete->pidl);
   
    //free the list item
		HeapFree(GetProcessHeap(),0,pDelete);
  }
  this->mpFirst = this->mpLast = this->mpCurrent = NULL;
  return TRUE;
}

/***********************************************************************
*   IShellFolder implementation
*/
/*LPSHELLFOLDER IShellFolder_Constructor();*/
static HRESULT WINAPI IShellFolder_QueryInterface(LPSHELLFOLDER,REFIID,LPVOID*);
static ULONG WINAPI IShellFolder_AddRef(LPSHELLFOLDER);
static ULONG WINAPI IShellFolder_Release(LPSHELLFOLDER);
static HRESULT WINAPI IShellFolder_Initialize(LPSHELLFOLDER,LPCITEMIDLIST);
static HRESULT WINAPI IShellFolder_ParseDisplayName(LPSHELLFOLDER,HWND32,LPBC,LPOLESTR32,DWORD*,LPITEMIDLIST*,DWORD*);
static HRESULT WINAPI IShellFolder_EnumObjects(LPSHELLFOLDER,HWND32,DWORD,LPENUMIDLIST*);
static HRESULT WINAPI IShellFolder_BindToObject(LPSHELLFOLDER,LPCITEMIDLIST,LPBC,REFIID,LPVOID*);
static HRESULT WINAPI IShellFolder_BindToStorage(LPSHELLFOLDER,LPCITEMIDLIST,LPBC,REFIID,LPVOID*);
static HRESULT WINAPI IShellFolder_CompareIDs(LPSHELLFOLDER,LPARAM,LPCITEMIDLIST,LPCITEMIDLIST);
static HRESULT WINAPI IShellFolder_CreateViewObject(LPSHELLFOLDER,HWND32,REFIID,LPVOID*);
static HRESULT WINAPI IShellFolder_GetAttributesOf(LPSHELLFOLDER,UINT32,LPCITEMIDLIST*,DWORD*);
static HRESULT WINAPI IShellFolder_GetUIObjectOf(LPSHELLFOLDER,HWND32,UINT32,LPCITEMIDLIST*,REFIID,UINT32*,LPVOID*);
static HRESULT WINAPI IShellFolder_GetDisplayNameOf(LPSHELLFOLDER,LPCITEMIDLIST,DWORD,LPSTRRET);
static HRESULT WINAPI IShellFolder_SetNameOf(LPSHELLFOLDER,HWND32,LPCITEMIDLIST,LPCOLESTR32,DWORD,LPITEMIDLIST*);
/***********************************************************************
*
*	  IShellFolder_VTable
*/
static struct IShellFolder_VTable sfvt = {
  IShellFolder_QueryInterface,
	IShellFolder_AddRef,
	IShellFolder_Release,
/*	IShellFolder_Initialize,*/
	IShellFolder_ParseDisplayName,
	IShellFolder_EnumObjects,
	IShellFolder_BindToObject,
  IShellFolder_BindToStorage,
  IShellFolder_CompareIDs,
	IShellFolder_CreateViewObject,
	IShellFolder_GetAttributesOf,
  IShellFolder_GetUIObjectOf,
  IShellFolder_GetDisplayNameOf,
  IShellFolder_SetNameOf
};
/**************************************************************************
*	  IShellFolder_Constructor
*/

LPSHELLFOLDER IShellFolder_Constructor(LPSHELLFOLDER pParent,LPITEMIDLIST pidl) {
	LPSHELLFOLDER	sf;
	DWORD dwSize=0;
	WORD wLen;
	sf = (LPSHELLFOLDER)HeapAlloc(GetProcessHeap(),0,sizeof(IShellFolder));
	sf->ref		= 1;
	sf->lpvtbl	= &sfvt;
  sf->mlpszFolder=NULL;
	sf->mpSFParent=pParent;

	TRACE(shell,"(%p)->(parent=%p, pidl=%p)\n",sf,pParent, pidl);
	
	/* create own pidl-manager*/
  sf->pPidlMgr  = PidlMgr_Constructor();
	if (! sf->pPidlMgr )
	{ HeapFree(GetProcessHeap(),0,sf);
	  ERR (shell,"-- Could not initialize PidMGR\n");
	  return NULL;
	}

  /* keep a copy of the pidl in the instance*/
	sf->mpidl = sf->pPidlMgr->lpvtbl->fnCopy(sf->pPidlMgr, pidl);
	sf->mpidlNSRoot = NULL;
	
  if(sf->mpidl)        /* do we have a pidl?*/
  { /*if(sf->pPidlMgr->lpvtbl->fnIsDesktop(sf->pPidlMgr,sf->mpidl))
    { sf->pPidlMgr->lpvtbl->fnGetDesktop(sf->pPidlMgr,sf->mpidl);
    }*/
    dwSize = 0;
    if(sf->mpSFParent->mlpszFolder)
    { dwSize += strlen(sf->mpSFParent->mlpszFolder) + 1;
    }   
    dwSize += sf->pPidlMgr->lpvtbl->fnGetFolderText(sf->pPidlMgr,sf->mpidl,NULL,0);
    sf->mlpszFolder = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwSize);
    if(sf->mlpszFolder)
    { *(sf->mlpszFolder) = 0;
      if(sf->mpSFParent->mlpszFolder)
      {  strcpy(sf->mlpszFolder, sf->mpSFParent->mlpszFolder);
         wLen = strlen(sf->mlpszFolder);
         if (wLen && sf->mlpszFolder[wLen-1]!='\\')
         { sf->mlpszFolder[wLen+0]='\\';
           sf->mlpszFolder[wLen+1]='\0';
         }
      }
      sf->pPidlMgr->lpvtbl->fnGetFolderText(sf->pPidlMgr, sf->mpidl, sf->mlpszFolder+strlen(sf->mlpszFolder), dwSize-strlen(sf->mlpszFolder));
    }
  }
	
	TRACE(shell,"-- (%p)->(%p,%p,%s)\n",sf,pParent, pidl, debugstr_a(sf->mlpszFolder));
	return sf;
}
/**************************************************************************
 *  IShellFolder::QueryInterface
 */
static HRESULT WINAPI IShellFolder_QueryInterface(
  LPSHELLFOLDER this, REFIID riid, LPVOID *ppvObj)
{  char	xriid[50];
   WINE_StringFromCLSID((LPCLSID)riid,xriid);
   TRACE(shell,"(%p)->(\n\tIID:\t%s,%p)\n",this,xriid,ppvObj);

  *ppvObj = NULL;

  if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
  { *ppvObj = this; 
  }
  else if(IsEqualIID(riid, &IID_IShellFolder))  /*IShellFolder*/
  {    *ppvObj = (IShellFolder*)this;
  }   

  if(*ppvObj)
  { (*(LPSHELLFOLDER*)ppvObj)->lpvtbl->fnAddRef(this);  	
    TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
		return S_OK;
  }
	TRACE(shell,"-- Interface: E_NOINTERFACE\n");
	return E_NOINTERFACE;
}   

/**************************************************************************
*  IShellFolder::AddRef
*/

static ULONG WINAPI IShellFolder_AddRef(LPSHELLFOLDER this)
{	TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
	return ++(this->ref);
}

/**************************************************************************
 *  IShellFolder_Release
 */
static ULONG WINAPI IShellFolder_Release(LPSHELLFOLDER this) 
{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
	if (!--(this->ref)) {
		TRACE(shell,"-- destroying IShellFolder(%p)\n",this);
		if (pdesktopfolder==this)
		{ pdesktopfolder=NULL;
		  TRACE(shell,"-- destroyed IShellFolder(%p) was Desktopfolder\n",this);
		}
		HeapFree(GetProcessHeap(),0,this);
		return 0;
	}
	return this->ref;
}
/**************************************************************************
*		IShellFolder_ParseDisplayName
*
* FIXME: 
*    pdwAttributes: not used
*/
static HRESULT WINAPI IShellFolder_ParseDisplayName(
	LPSHELLFOLDER this,
	HWND32 hwndOwner,
	LPBC pbcReserved,
	LPOLESTR32 lpszDisplayName,    /* [in]  name of file or folder*/
	DWORD *pchEaten,               /* [out] number of chars parsed*/
	LPITEMIDLIST *ppidl,           /* [out] the pidl*/
	DWORD *pdwAttributes)
{	HRESULT        hr=E_OUTOFMEMORY;
  LPITEMIDLIST   pidlFull=NULL, pidlTemp = NULL, pidlOld = NULL;
  LPSTR          pszNext=NULL;
  CHAR           szElement[MAX_PATH];
  BOOL32         bType;

  DWORD          dwChars=lstrlen32W(lpszDisplayName) + 1;
  LPSTR          pszTemp=(LPSTR)HeapAlloc(GetProcessHeap(),0,dwChars * sizeof(CHAR));
       
  TRACE(shell,"(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
	this,hwndOwner,pbcReserved,lpszDisplayName,debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);

  if(pszTemp)
  { hr = E_FAIL;
    WideCharToLocal32(pszTemp, lpszDisplayName, dwChars);
    if(*pszTemp)
    { if (strcmp(pszTemp,"Desktop")==0)
		  { pidlFull = (LPITEMIDLIST)HeapAlloc(GetProcessHeap(),0,sizeof(ITEMIDLIST));
			  pidlFull->mkid.cb = 0;
        pidlFull->mkid.abID[0] = 0;
			}
		  else
			{ pidlFull = this->pPidlMgr->lpvtbl->fnCreateMyComputer(this->pPidlMgr);

        /* check if the lpszDisplayName is Folder or File*/
  			bType = ! (GetFileAttributes32A(pszNext)&FILE_ATTRIBUTE_DIRECTORY);
  			pszNext = GetNextElement(pszTemp, szElement, MAX_PATH);
  
        pidlTemp = this->pPidlMgr->lpvtbl->fnCreateDrive(this->pPidlMgr,szElement);			
        pidlOld = pidlFull;
        pidlFull = this->pPidlMgr->lpvtbl->fnConcatenate(this->pPidlMgr,pidlFull,pidlTemp);
  	    this->pPidlMgr->lpvtbl->fnDelete(this->pPidlMgr,pidlOld);
  
  			if(pidlFull)
        { while((pszNext=GetNextElement(pszNext, szElement, MAX_PATH)))
          { if(!*pszNext && bType)
  					{ pidlTemp = this->pPidlMgr->lpvtbl->fnCreateValue(this->pPidlMgr,szElement);
  					}
  					else				
            { pidlTemp = this->pPidlMgr->lpvtbl->fnCreateFolder(this->pPidlMgr,szElement);
  					}
            pidlOld = pidlFull;
            pidlFull = this->pPidlMgr->lpvtbl->fnConcatenate(this->pPidlMgr,pidlFull,pidlTemp);
            this->pPidlMgr->lpvtbl->fnDelete(this->pPidlMgr,pidlOld);
          }
          hr = S_OK;
        }
      }
		}
  }
	HeapFree(GetProcessHeap(),0,pszTemp);
  *ppidl = pidlFull;
  return hr;
}

/**************************************************************************
*		IShellFolder_EnumObjects
*/
static HRESULT WINAPI IShellFolder_EnumObjects(
	LPSHELLFOLDER this,
	HWND32 hwndOwner,
	DWORD dwFlags,
	LPENUMIDLIST* ppEnumIDList)
{ HRESULT  hr;
	TRACE(shell,"(%p)->(HWND=0x%08x,0x%08lx,%p)\n",this,hwndOwner,dwFlags,ppEnumIDList);

  *ppEnumIDList = NULL;
	*ppEnumIDList = IEnumIDList_Constructor (this->mlpszFolder, dwFlags, &hr);
  TRACE(shell,"-- (%p)->(new ID List: %p)\n",this,*ppEnumIDList);
  if(!*ppEnumIDList)
  { return hr;
  }
  return S_OK;		
}
/**************************************************************************
 *  IShellFolder_Initialize()
 *  IPersistFolder Method
 */
static HRESULT WINAPI IShellFolder_Initialize(
	LPSHELLFOLDER this,
	LPCITEMIDLIST pidl)
{ TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl);
  if(this->mpidlNSRoot)
  { this->pPidlMgr->lpvtbl->fnDelete(this->pPidlMgr, this->mpidlNSRoot);
    this->mpidlNSRoot = NULL;
  }
  this->mpidlNSRoot = this->pPidlMgr->lpvtbl->fnCopy(this->pPidlMgr, pidl);
  return S_OK;
}

/**************************************************************************
*		IShellFolder_BindToObject
*/
static HRESULT WINAPI IShellFolder_BindToObject(
	LPSHELLFOLDER this,
	LPCITEMIDLIST pidl,
	LPBC pbcReserved,
	REFIID riid,
	LPVOID * ppvOut)
{	char	        xriid[50];
  HRESULT       hr;
	LPSHELLFOLDER pShellFolder;
	
	WINE_StringFromCLSID(riid,xriid);

	TRACE(shell,"(%p)->(pidl=%p,%p,\n\tIID:%s,%p)\n",this,pidl,pbcReserved,xriid,ppvOut);

  *ppvOut = NULL;
  pShellFolder = IShellFolder_Constructor(this, pidl);
  if(!pShellFolder)
    return E_OUTOFMEMORY;
/*  pShellFolder->lpvtbl->fnInitialize(pShellFolder, this->mpidlNSRoot);*/
  IShellFolder_Initialize(pShellFolder, this->mpidlNSRoot);
  hr = pShellFolder->lpvtbl->fnQueryInterface(pShellFolder, riid, ppvOut);
  pShellFolder->lpvtbl->fnRelease(pShellFolder);
	TRACE(shell,"-- (%p)->(interface=%p)\n",this, ppvOut);
  return hr;
}

/**************************************************************************
*  IShellFolder_BindToStorage
*/
static HRESULT WINAPI IShellFolder_BindToStorage(
  	LPSHELLFOLDER this,
    LPCITEMIDLIST pidl, 
    LPBC pbcReserved, 
    REFIID riid, 
    LPVOID *ppvOut)
{	char xriid[50];
	WINE_StringFromCLSID(riid,xriid);

	FIXME(shell,"(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",this,pidl,pbcReserved,xriid,ppvOut);

  *ppvOut = NULL;
  return E_NOTIMPL;
}

/**************************************************************************
*  IShellFolder_CompareIDs
*/
static HRESULT WINAPI  IShellFolder_CompareIDs(
  	LPSHELLFOLDER this,
		LPARAM lParam, 
    LPCITEMIDLIST pidl1, 
    LPCITEMIDLIST pidl2)
{ CHAR szString1[MAX_PATH] = "";
  CHAR szString2[MAX_PATH] = "";
  int   nReturn;
  LPCITEMIDLIST  pidlTemp1 = pidl1, pidlTemp2 = pidl2;

  TRACE(shell,"(%p)->(0x%08lx,pidl1=%p,pidl2=%p) stub\n",this,lParam,pidl1,pidl2);

  /*Special case - If one of the items is a Path and the other is a File, always 
  make the Path come before the File.*/

  //get the last item in each list
  while((this->pPidlMgr->lpvtbl->fnGetNextItem(this->pPidlMgr,pidlTemp1))->mkid.cb)
    pidlTemp1 = this->pPidlMgr->lpvtbl->fnGetNextItem(this->pPidlMgr,pidlTemp1);
  while((this->pPidlMgr->lpvtbl->fnGetNextItem(this->pPidlMgr,pidlTemp2))->mkid.cb)
    pidlTemp2 = this->pPidlMgr->lpvtbl->fnGetNextItem(this->pPidlMgr,pidlTemp2);

  //at this point, both pidlTemp1 and pidlTemp2 point to the last item in the list
  if(this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr,pidlTemp1) != this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr,pidlTemp2))
  { if(this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr,pidlTemp1))
      return 1;
   return -1;
  }

  this->pPidlMgr->lpvtbl->fnGetDrive(this->pPidlMgr, pidl1,szString1,sizeof(szString1));
  this->pPidlMgr->lpvtbl->fnGetDrive(this->pPidlMgr, pidl2,szString1,sizeof(szString2));
  nReturn = strcasecmp(szString1, szString2);
  if(nReturn)
    return nReturn;

  this->pPidlMgr->lpvtbl->fnGetFolderText(this->pPidlMgr, pidl1,szString1,sizeof(szString1));
  this->pPidlMgr->lpvtbl->fnGetFolderText(this->pPidlMgr, pidl2,szString2,sizeof(szString2));
  nReturn = strcasecmp(szString1, szString2);
  if(nReturn)
    return nReturn;

  this->pPidlMgr->lpvtbl->fnGetValueText(this->pPidlMgr,pidl1,szString1,sizeof(szString1));
  this->pPidlMgr->lpvtbl->fnGetValueText(this->pPidlMgr,pidl2,szString2,sizeof(szString2));
  return strcasecmp(szString1, szString2);
}

/**************************************************************************
*	  IShellFolder_CreateViewObject
* NOTES
*  the same as SHCreateShellFolderViewEx ???
*/
static HRESULT WINAPI IShellFolder_CreateViewObject(
	LPSHELLFOLDER this,
	HWND32 hwndOwner,
	REFIID riid,
	LPVOID *ppvOut)
{	char	xriid[50];

	WINE_StringFromCLSID(riid,xriid);
	FIXME(shell,"(%p)->(0x%04x,\n\tIID:\t%s,%p),stub!\n",this,hwndOwner,xriid,ppvOut);
	
	*ppvOut = NULL;
	return E_NOTIMPL;
}

/**************************************************************************
*  IShellFolder_GetAttributesOf
*/
static HRESULT WINAPI IShellFolder_GetAttributesOf(
	LPSHELLFOLDER this,
	UINT32 cidl,
	LPCITEMIDLIST *apidl,
	DWORD *rgfInOut)
{ FIXME(shell,"(%p)->(%d,%p,%p),stub!\n",this,cidl,apidl,rgfInOut);
	return E_NOTIMPL;
}
/**************************************************************************
*  IShellFolder_GetUIObjectOf
*/
static HRESULT WINAPI IShellFolder_GetUIObjectOf(
	LPSHELLFOLDER this,
	HWND32 hwndOwner,
	UINT32 cidl, 
	LPCITEMIDLIST * apidl,
  REFIID riid,
	UINT32 * prgfInOut,
	LPVOID * ppvOut)
{ char	        xclsid[50];
  
	WINE_StringFromCLSID(riid,xclsid);

  FIXME(shell,"(%p)->(%u,%u,pidl=%p,\n\tIID:%s,%p,%p),stub!\n",
	  this,hwndOwner,cidl,apidl,xclsid,prgfInOut,ppvOut);

	*ppvOut = NULL;	
	return E_NOTIMPL;
}
/**************************************************************************
*  IShellFolder_GetDisplayNameOf
*
* FIXME
*  if the name is in the pidl the ret value should be a STRRET_OFFSET
*/
#define GET_SHGDN_FOR(dwFlags)         ((DWORD)dwFlags & (DWORD)0x0000FF00)
#define GET_SHGDN_RELATION(dwFlags)    ((DWORD)dwFlags & (DWORD)0x000000FF)

static HRESULT WINAPI IShellFolder_GetDisplayNameOf( 
  	LPSHELLFOLDER this,
    LPCITEMIDLIST pidl, 
    DWORD dwFlags, 
    LPSTRRET lpName)
{ CHAR           szText[MAX_PATH];
  CHAR           szTemp[MAX_PATH];
	CHAR           szSpecial[MAX_PATH];
	CHAR           szDrive[MAX_PATH];
  DWORD          dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags;
  LPITEMIDLIST   pidlTemp=NULL;
	BOOL32				 bSimplePidl=FALSE;
		
  TRACE(shell,"(%p)->(pidl=%p,0x%08lx,%p)\n",this,pidl,dwFlags,lpName);

  /* test if simple(relative) or complex(absolute) pidl */
  pidlTemp = this->pPidlMgr->lpvtbl->fnGetNextItem(this->pPidlMgr,pidl);
	if (pidlTemp->mkid.cb==0x00)
	{ bSimplePidl = TRUE;
	}
	if (this->pPidlMgr->lpvtbl->fnIsDesktop(this->pPidlMgr, pidl))
	{ strcpy (szText,"Desktop");
	}
	else
	{	szSpecial[0]=0x00;
	  if (this->pPidlMgr->lpvtbl->fnIsMyComputer(this->pPidlMgr, pidl))
    { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidl, szSpecial, MAX_PATH);
    }
		szDrive[0]=0x00;
	  if (this->pPidlMgr->lpvtbl->fnIsDrive(this->pPidlMgr, pidl))
		{ pidlTemp = this->pPidlMgr->lpvtbl->fnGetLastItem(this->pPidlMgr,pidl);
  		if (pidlTemp)
      { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidlTemp, szTemp, MAX_PATH);
  		}
		  if ( dwFlags==SHGDN_NORMAL || dwFlags==SHGDN_INFOLDER)
  		{ GetVolumeInformation32A(szTemp,szDrive,MAX_PATH,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
				if (szTemp[2]=='\\')
				{ szTemp[2]='\0';
				}
        strcat (szDrive," (");
				strcat (szDrive,szTemp);
				strcat (szDrive,")"); 
  		}
			else
			{  PathAddBackslash (szTemp);
			   strcpy(szDrive,szTemp);
			}
		}
		
  	switch(dwFlags)
    { case SHGDN_NORMAL:
        this->pPidlMgr->lpvtbl->fnGetPidlPath(this->pPidlMgr, pidl, szText, MAX_PATH);
        break;
      case SHGDN_INFOLDER:
        pidlTemp = this->pPidlMgr->lpvtbl->fnGetLastItem(this->pPidlMgr,pidl);
  			if (pidlTemp)
        { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidlTemp, szText, MAX_PATH);
  			}
   			break;				
   		case	SHGDN_FORPARSING:
			  if (bSimplePidl)
				{ /* if the IShellFolder has parents, get the path from the
				  parent and add the ItemName*/
				  if (this->mlpszFolder && strlen (this->mlpszFolder))
  			  { strcpy (szText,this->mlpszFolder);
  			    PathAddBackslash (szText);
  			  }
    			else
    			{ strcpy(szText,"");
  		  	}
          pidlTemp = this->pPidlMgr->lpvtbl->fnGetLastItem(this->pPidlMgr,pidl);
        	if (pidlTemp)
          { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidlTemp, szTemp, MAX_PATH );
        	} 
					strcat(szText,szTemp);
				}
				else					
				{ /* if the pidl is absolute, get everything from the pidl*/
				  this->pPidlMgr->lpvtbl->fnGetPidlPath(this->pPidlMgr, pidl, szText, MAX_PATH);
				}
        break;
      default:    return E_INVALIDARG;
    }
		if ((szText[0]==0x00 && szDrive[0]!=0x00)|| (bSimplePidl && szDrive[0]!=0x00))
		{ strcpy(szText,szDrive);
		}
		if (szText[0]==0x00 && szSpecial[0]!=0x00)
		{ strcpy(szText,szSpecial);
		}
 
  }
  
  TRACE(shell,"-- (%p)->(%s,%s,%s)\n",this,szSpecial,szDrive,szText);

  if(!(lpName))
  {  return E_OUTOFMEMORY;
	}
  lpName->uType = STRRET_CSTR;	
	strcpy(lpName->u.cStr,szText);
  return S_OK;
}

/**************************************************************************
*  IShellFolder_SetNameOf
*/
static HRESULT WINAPI IShellFolder_SetNameOf(
  	LPSHELLFOLDER this,
		HWND32 hwndOwner, 
    LPCITEMIDLIST pidl, 
    LPCOLESTR32 lpName, 
    DWORD dw, 
    LPITEMIDLIST *pPidlOut)
{  FIXME(shell,"(%p)->(%u,pidl=%p,%s,%lu,%p),stub!\n",
	  this,hwndOwner,pidl,debugstr_w(lpName),dw,pPidlOut);
	 return E_NOTIMPL;
}

/**************************************************************************
*	  IShellLink_VTable
*/
static struct IShellLink_VTable slvt = {
    (void *)1,
    (void *)2,
    (void *)3,
    (void *)4,
    (void *)5,
    (void *)6,
    (void *)7,
    (void *)8,
    (void *)9,
    (void *)10,
    (void *)11,
    (void *)12,
    (void *)13,
    (void *)14,
    (void *)15,
    (void *)16,
    (void *)17,
    (void *)18,
    (void *)19,
    (void *)20,
    (void *)21
};

/**************************************************************************
 *	  IShellLink_Constructor
 */
LPSHELLLINK IShellLink_Constructor() 
{	LPSHELLLINK sl;

	sl = (LPSHELLLINK)HeapAlloc(GetProcessHeap(),0,sizeof(IShellLink));
	sl->ref = 1;
	sl->lpvtbl = &slvt;
	TRACE(shell,"(%p)->()\n",sl);
	return sl;
}

/**************************************************************************
*	  INTERNAL CLASS pidlmgr
*/
LPITEMIDLIST PidlMgr_CreateDesktop(LPPIDLMGR);
LPITEMIDLIST PidlMgr_CreateMyComputer(LPPIDLMGR);
LPITEMIDLIST PidlMgr_CreateDrive(LPPIDLMGR,LPCSTR);
LPITEMIDLIST PidlMgr_CreateFolder(LPPIDLMGR,LPCSTR);
LPITEMIDLIST PidlMgr_CreateValue(LPPIDLMGR,LPCSTR);
void PidlMgr_Delete(LPPIDLMGR,LPITEMIDLIST);
LPITEMIDLIST PidlMgr_GetNextItem(LPPIDLMGR,LPITEMIDLIST);
LPITEMIDLIST PidlMgr_Copy(LPPIDLMGR,LPITEMIDLIST);
UINT16 PidlMgr_GetSize(LPPIDLMGR,LPITEMIDLIST);
BOOL32 PidlMgr_GetDesktop(LPPIDLMGR,LPCITEMIDLIST,LPSTR);
BOOL32 PidlMgr_GetDrive(LPPIDLMGR,LPCITEMIDLIST,LPSTR,UINT16);
LPITEMIDLIST PidlMgr_GetLastItem(LPPIDLMGR,LPCITEMIDLIST);
DWORD PidlMgr_GetItemText(LPPIDLMGR,LPCITEMIDLIST,LPSTR,UINT16);
BOOL32 PidlMgr_IsDesktop(LPPIDLMGR,LPCITEMIDLIST);
BOOL32 PidlMgr_IsMyComputer(LPPIDLMGR,LPCITEMIDLIST);
BOOL32 PidlMgr_IsDrive(LPPIDLMGR,LPCITEMIDLIST);
BOOL32 PidlMgr_IsFolder(LPPIDLMGR,LPCITEMIDLIST);
BOOL32 PidlMgr_IsValue(LPPIDLMGR,LPCITEMIDLIST);
BOOL32 PidlMgr_HasFolders(LPPIDLMGR,LPSTR,LPCITEMIDLIST);
DWORD PidlMgr_GetFolderText(LPPIDLMGR,LPCITEMIDLIST,LPSTR,DWORD);
DWORD PidlMgr_GetValueText(LPPIDLMGR,LPCITEMIDLIST,LPSTR,DWORD);
BOOL32 PidlMgr_GetValueType(LPPIDLMGR,LPCITEMIDLIST,LPCITEMIDLIST,LPDWORD);
DWORD PidlMgr_GetDataText(LPPIDLMGR,LPCITEMIDLIST,LPCITEMIDLIST,LPSTR,DWORD);
DWORD PidlMgr_GetPidlPath(LPPIDLMGR,LPCITEMIDLIST,LPSTR,DWORD);
LPITEMIDLIST PidlMgr_Concatenate(LPPIDLMGR,LPITEMIDLIST,LPITEMIDLIST);
LPITEMIDLIST PidlMgr_Create(LPPIDLMGR,PIDLTYPE,LPVOID,UINT16);
DWORD PidlMgr_GetData(LPPIDLMGR,PIDLTYPE,LPCITEMIDLIST,LPVOID,UINT16);
LPPIDLDATA PidlMgr_GetDataPointer(LPPIDLMGR,LPCITEMIDLIST);
BOOL32 PidlMgr_SeparatePathAndValue(LPPIDLMGR,LPITEMIDLIST,LPITEMIDLIST*,LPITEMIDLIST*);

static struct PidlMgr_VTable pmgrvt = {
    PidlMgr_CreateDesktop,
    PidlMgr_CreateMyComputer,
		PidlMgr_CreateDrive,
    PidlMgr_CreateFolder,
    PidlMgr_CreateValue,
		PidlMgr_Delete,
    PidlMgr_GetNextItem,
    PidlMgr_Copy,
    PidlMgr_GetSize,
    PidlMgr_GetDesktop,
		PidlMgr_GetDrive,
    PidlMgr_GetLastItem,
    PidlMgr_GetItemText,
    PidlMgr_IsDesktop,
    PidlMgr_IsMyComputer,
		PidlMgr_IsDrive,
    PidlMgr_IsFolder,
    PidlMgr_IsValue,
    PidlMgr_HasFolders,
    PidlMgr_GetFolderText,
    PidlMgr_GetValueText,
    PidlMgr_GetValueType,
    PidlMgr_GetDataText,
    PidlMgr_GetPidlPath,
		PidlMgr_Concatenate,
    PidlMgr_Create,
    PidlMgr_GetData,
    PidlMgr_GetDataPointer,
    PidlMgr_SeparatePathAndValue
};
/**************************************************************************
 *	  PidlMgr_Constructor
 */
LPPIDLMGR PidlMgr_Constructor() 
{	LPPIDLMGR pmgr;
	pmgr = (LPPIDLMGR)HeapAlloc(GetProcessHeap(),0,sizeof(pidlmgr));
	pmgr->lpvtbl = &pmgrvt;
	TRACE(shell,"(%p)->()\n",pmgr);
  /** FIXME DllRefCount++;*/
	return pmgr;
}
/**************************************************************************
 *	  PidlMgr_Destructor
 */
void PidlMgr_Destructor(LPPIDLMGR this) 
{	HeapFree(GetProcessHeap(),0,this);
 	TRACE(shell,"(%p)->()\n",this);
  /** FIXME DllRefCount--;*/
}

/**************************************************************************
 *  PidlMgr_CreateDesktop()
 *  PidlMgr_CreateDrive()
 *  PidlMgr_CreateFolder() 
 *  PidlMgr_CreateValue()
 */
LPITEMIDLIST PidlMgr_CreateDesktop(LPPIDLMGR this)
{ TRACE(shell,"(%p)->()\n",this);
    return PidlMgr_Create(this,PT_DESKTOP, NULL, 0);
}
LPITEMIDLIST PidlMgr_CreateMyComputer(LPPIDLMGR this)
{ TRACE(shell,"(%p)->()\n",this);
  return PidlMgr_Create(this,PT_MYCOMP, (void *)"My Computer", sizeof("My Computer"));
}
LPITEMIDLIST PidlMgr_CreateDrive(LPPIDLMGR this, LPCSTR lpszNew)
{ char sTemp[4];
  strncpy (sTemp,lpszNew,4);
	sTemp[2]='\\';
	sTemp[3]=0x00;
  TRACE(shell,"(%p)->(%s)\n",this,sTemp);
  return PidlMgr_Create(this,PT_DRIVE,(LPVOID)&sTemp[0],4);
}
LPITEMIDLIST PidlMgr_CreateFolder(LPPIDLMGR this, LPCSTR lpszNew)
{ TRACE(shell,"(%p)->(%s)\n",this,lpszNew);
  return PidlMgr_Create(this,PT_FOLDER, (LPVOID)lpszNew, strlen(lpszNew)+1);
}
LPITEMIDLIST PidlMgr_CreateValue(LPPIDLMGR this,LPCSTR lpszNew)
{ TRACE(shell,"(%p)->(%s)\n",this,lpszNew);
  return PidlMgr_Create(this,PT_VALUE, (LPVOID)lpszNew, strlen(lpszNew)+1);
}
/**************************************************************************
 *  PidlMgr_Delete()
 *  Deletes a PIDL
 */
void PidlMgr_Delete(LPPIDLMGR this,LPITEMIDLIST pidl)
{ TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl);
  HeapFree(GetProcessHeap(),0,pidl);
}

/**************************************************************************
 *  PidlMgr_GetNextItem()
 */
LPITEMIDLIST PidlMgr_GetNextItem(LPPIDLMGR this, LPITEMIDLIST pidl)
{ LPITEMIDLIST nextpidl;

  TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl);
  if(pidl)
  { nextpidl = (LPITEMIDLIST)(LPBYTE)(((LPBYTE)pidl) + pidl->mkid.cb);
/*    TRACE(shell,"-- (%p)->(next pidl=%p)\n",this,nextpidl);*/
		return nextpidl;
	}
  else
  {  return (NULL);
	}
}

/**************************************************************************
 *  PidlMgr_Copy()
 */
LPITEMIDLIST PidlMgr_Copy(LPPIDLMGR this, LPITEMIDLIST pidlSource)
{ LPITEMIDLIST pidlTarget = NULL;
  UINT16 cbSource = 0;

	TRACE(shell,"(%p)->(pidl=%p)\n",this,pidlSource);

  if(NULL == pidlSource)
 	{  TRACE(shell,"-- (%p)->(%p)\n",this,pidlSource);
     return (NULL);
	}

  cbSource = PidlMgr_GetSize(this, pidlSource);
  pidlTarget = (LPITEMIDLIST)HeapAlloc(GetProcessHeap(),0,cbSource);
  if(!pidlTarget)
  { return (NULL);
	}

  memcpy(pidlTarget, pidlSource, cbSource);

	TRACE(shell,"-- (%p)->(pidl=%p to new pidl=%p)\n",this,pidlSource,pidlTarget);
  return pidlTarget;
}
/**************************************************************************
 *  PidlMgr_GetSize()
 *  calculates the size of the complete pidl
 */
UINT16 PidlMgr_GetSize(LPPIDLMGR this, LPITEMIDLIST pidl)
{ UINT16 cbTotal = 0;
  LPITEMIDLIST pidlTemp = pidl;

  TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl);
  if(pidlTemp)
  { while(pidlTemp->mkid.cb)
    { cbTotal += pidlTemp->mkid.cb;
      pidlTemp = PidlMgr_GetNextItem(this, pidlTemp);
    }  
    //add the size of the NULL terminating ITEMIDLIST
    cbTotal += sizeof(ITEMIDLIST);
  }
	TRACE(shell,"-- size %u\n",cbTotal);
  return (cbTotal);
}
/**************************************************************************
 *  PidlMgr_GetDesktop()
 * 
 *  FIXME: quick hack
 */
BOOL32 PidlMgr_GetDesktop(LPPIDLMGR this,LPCITEMIDLIST pidl,LPSTR pOut)
{ TRACE(shell,"(%p)->(%p %p)\n",this,pidl,pOut);
  return (BOOL32)PidlMgr_GetData(this,PT_DESKTOP, pidl, (LPVOID)pOut, 255);
}
/**************************************************************************
 *  PidlMgr_GetDrive()
 *
 *  FIXME: quick hack
 */
BOOL32 PidlMgr_GetDrive(LPPIDLMGR this,LPCITEMIDLIST pidl,LPSTR pOut, UINT16 uSize)
{ LPITEMIDLIST   pidlTemp=NULL;

  TRACE(shell,"(%p)->(%p,%p,%u)\n",this,pidl,pOut,uSize);
  if(PidlMgr_IsMyComputer(this,pidl))
  { pidlTemp = PidlMgr_GetNextItem(this,pidl);
	}
	else if (PidlMgr_IsDrive(this,pidlTemp))
  { return (BOOL32)PidlMgr_GetData(this,PT_DRIVE, pidlTemp, (LPVOID)pOut, uSize);
	}
	return FALSE;
}
/**************************************************************************
 *  PidlMgr_GetLastItem()
 *  Gets the last item in the list
 */
LPITEMIDLIST PidlMgr_GetLastItem(LPPIDLMGR this,LPCITEMIDLIST pidl)
{ LPITEMIDLIST   pidlLast = NULL;

  TRACE(shell,"(%p)->(pidl=%p)\n",this,pidl);

  if(pidl)
  { while(pidl->mkid.cb)
    { pidlLast = (LPITEMIDLIST)pidl;
      pidl = PidlMgr_GetNextItem(this,pidl);
    }  
  }
  return pidlLast;
}
/**************************************************************************
 *  PidlMgr_GetItemText()
 *  Gets the text for only this item
 */
DWORD PidlMgr_GetItemText(LPPIDLMGR this,LPCITEMIDLIST pidl, LPSTR lpszText, UINT16 uSize)
{ TRACE(shell,"(%p)->(pidl=%p %p %x)\n",this,pidl,lpszText,uSize);
  if (PidlMgr_IsMyComputer(this, pidl))
  { return PidlMgr_GetData(this,PT_MYCOMP, pidl, (LPVOID)lpszText, uSize);
	}
	if (PidlMgr_IsDrive(this, pidl))
	{ return PidlMgr_GetData(this,PT_DRIVE, pidl, (LPVOID)lpszText, uSize);
	}
	return PidlMgr_GetData(this,PT_TEXT, pidl, (LPVOID)lpszText, uSize);	
}
/**************************************************************************
 *  PidlMgr_IsDesktop()
 *  PidlMgr_IsDrive()
 *  PidlMgr_IsFolder()
 *  PidlMgr_IsValue()
*/
BOOL32 PidlMgr_IsDesktop(LPPIDLMGR this,LPCITEMIDLIST pidl)
{ TRACE(shell,"%p->(%p)\n",this,pidl);
  return (  pidl->mkid.cb == 0x00 );
}

BOOL32 PidlMgr_IsMyComputer(LPPIDLMGR this,LPCITEMIDLIST pidl)
{ LPPIDLDATA  pData;
  TRACE(shell,"%p->(%p)\n",this,pidl);
  pData = PidlMgr_GetDataPointer(this,pidl);
  return (PT_MYCOMP == pData->type);
}

BOOL32 PidlMgr_IsDrive(LPPIDLMGR this,LPCITEMIDLIST pidl)
{ LPPIDLDATA  pData;
  TRACE(shell,"%p->(%p)\n",this,pidl);
  pData = PidlMgr_GetDataPointer(this,pidl);
  return (PT_DRIVE == pData->type);
}

BOOL32 PidlMgr_IsFolder(LPPIDLMGR this,LPCITEMIDLIST pidl)
{ LPPIDLDATA  pData;
  TRACE(shell,"%p->(%p)\n",this,pidl);
  pData = PidlMgr_GetDataPointer(this,pidl);
  return (PT_FOLDER == pData->type);
}

BOOL32 PidlMgr_IsValue(LPPIDLMGR this,LPCITEMIDLIST pidl)
{ LPPIDLDATA  pData;
  TRACE(shell,"%p->(%p)\n",this,pidl);
  pData = PidlMgr_GetDataPointer(this,pidl);
  return (PT_VALUE == pData->type);
}
/**************************************************************************
 * PidlMgr_HasFolders()
 * fixme: quick hack
 */
BOOL32 PidlMgr_HasFolders(LPPIDLMGR this, LPSTR pszPath, LPCITEMIDLIST pidl)
{ BOOL32 bResult= FALSE;
  WIN32_FIND_DATA32A stffile;	
  HANDLE32 hFile;

  TRACE (shell,"(%p)->%p %p\n",this, pszPath, pidl);
	
  hFile = FindFirstFile32A(pszPath,&stffile);
  do
  { if (! (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
    {  bResult= TRUE;
		}
  } while( FindNextFile32A(hFile,&stffile));
  FindClose32 (hFile);
	
	return bResult;
}


/**************************************************************************
 *  PidlMgr_GetFolderText()
 *  Creates a Path string from a PIDL, filtering out the special Folders 
 */
DWORD PidlMgr_GetFolderText(LPPIDLMGR this,LPCITEMIDLIST pidl,
   LPSTR lpszPath, DWORD dwSize)
{ LPITEMIDLIST   pidlTemp;
  DWORD          dwCopied = 0;
 
  TRACE(shell,"(%p)->(%p)\n",this,pidl);
 
  if(!pidl)
  { return 0;
	}

  if(PidlMgr_IsMyComputer(this,pidl))
  { pidlTemp = PidlMgr_GetNextItem(this,pidl);
	}
  else
  { pidlTemp = (LPITEMIDLIST)pidl;
	}

  //if this is NULL, return the required size of the buffer
  if(!lpszPath)
  { while(pidlTemp->mkid.cb)
    { LPPIDLDATA  pData = PidlMgr_GetDataPointer(this,pidlTemp);
      
      //add the length of this item plus one for the backslash
      dwCopied += strlen(pData->szText) + 1;  /* fixme pData->szText is not every time a string*/

      pidlTemp = PidlMgr_GetNextItem(this,pidlTemp);
    }

    //add one for the NULL terminator
	  TRACE(shell,"-- (%p)->(size=%lu)\n",this,dwCopied);
    return dwCopied + 1;
  }

  *lpszPath = 0;

  while(pidlTemp->mkid.cb && (dwCopied < dwSize))
  { LPPIDLDATA  pData = PidlMgr_GetDataPointer(this,pidlTemp);

    //if this item is a value, then skip it and finish
    if(PT_VALUE == pData->type)
    { break;
		}
   
    strcat(lpszPath, pData->szText);
    strcat(lpszPath, "\\");
    dwCopied += strlen(pData->szText) + 1;
    pidlTemp = PidlMgr_GetNextItem(this,pidlTemp);

		TRACE(shell,"-- (%p)->(size=%lu,%s)\n",this,dwCopied,lpszPath);
  }

  //remove the last backslash if necessary
  if(dwCopied)
  { if(*(lpszPath + strlen(lpszPath) - 1) == '\\')
    { *(lpszPath + strlen(lpszPath) - 1) = 0;
      dwCopied--;
    }
  }
  TRACE(shell,"-- (%p)->(path=%s)\n",this,lpszPath);
  return dwCopied;
}


/**************************************************************************
 *  PidlMgr_GetValueText()
 *  Gets the text for the last item in the list
 */
DWORD PidlMgr_GetValueText(LPPIDLMGR this,
    LPCITEMIDLIST pidl, LPSTR lpszValue, DWORD dwSize)
{ LPITEMIDLIST  pidlTemp=pidl;
  CHAR          szText[MAX_PATH];

  TRACE(shell,"(%p)->(pidl=%p %p 0x%08lx)\n",this,pidl,lpszValue,dwSize);

  if(!pidl)
  { return 0;
	}
		
  while(pidlTemp->mkid.cb && !PidlMgr_IsValue(this,pidlTemp))
  { pidlTemp = PidlMgr_GetNextItem(this,pidlTemp);
  }

  if(!pidlTemp->mkid.cb)
  { return 0;
	}

  PidlMgr_GetItemText(this, pidlTemp, szText, sizeof(szText));

  if(!lpszValue)
  { return strlen(szText) + 1;
  }
  strcpy(lpszValue, szText);
	TRACE(shell,"-- (%p)->(pidl=%p %p=%s 0x%08lx)\n",this,pidl,lpszValue,lpszValue,dwSize);
  return strlen(lpszValue);
}
/**************************************************************************
 *  PidlMgr_GetValueType()
 */
BOOL32 PidlMgr_GetValueType( LPPIDLMGR this,
   LPCITEMIDLIST pidlPath,
   LPCITEMIDLIST pidlValue,
   LPDWORD pdwType)
{ LPSTR    lpszFolder,
           lpszValueName;
  DWORD    dwNameSize;
 
  FIXME(shell,"(%p)->(%p %p %p) stub\n",this,pidlPath,pidlValue,pdwType);
	
  if(!pidlPath)
  { return FALSE;
	}

  if(!pidlValue)
  { return FALSE;
	}

  if(!pdwType)
  { return FALSE;
	}

  //get the Desktop
  //PidlMgr_GetDesktop(this,pidlPath);

  /* fixme: add the driveletter here*/
	
  //assemble the Folder string
  dwNameSize = PidlMgr_GetFolderText(this,pidlPath, NULL, 0);
  lpszFolder = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize);
  if(!lpszFolder)
  {  return FALSE;
	}
  PidlMgr_GetFolderText(this,pidlPath, lpszFolder, dwNameSize);

  //assemble the value name
  dwNameSize = PidlMgr_GetValueText(this,pidlValue, NULL, 0);
  lpszValueName = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize);
  if(!lpszValueName)
  { HeapFree(GetProcessHeap(),0,lpszFolder);
    return FALSE;
  }
  PidlMgr_GetValueText(this,pidlValue, lpszValueName, dwNameSize);

  /* fixme: we've got the path now do something with it
	  -like get the filetype*/
	
	pdwType=NULL;
	
  HeapFree(GetProcessHeap(),0,lpszFolder);
  HeapFree(GetProcessHeap(),0,lpszValueName);
  return TRUE;
}
/**************************************************************************
 *  PidlMgr_GetDataText()
 */
DWORD PidlMgr_GetDataText( LPPIDLMGR this,
 LPCITEMIDLIST pidlPath, LPCITEMIDLIST pidlValue, LPSTR lpszOut, DWORD dwOutSize)
{ LPSTR    lpszFolder,
           lpszValueName;
  DWORD    dwNameSize;

  FIXME(shell,"(%p)->(pidl=%p pidl=%p) stub\n",this,pidlPath,pidlValue);

  if(!lpszOut)
  { return FALSE;
	}

  if(!pidlPath)
  { return FALSE;
	}

  if(!pidlValue)
  { return FALSE;
	}

  /* fixme: get the driveletter*/

  //assemble the Folder string
  dwNameSize = PidlMgr_GetFolderText(this,pidlPath, NULL, 0);
  lpszFolder = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize);
  if(!lpszFolder)
  {  return FALSE;
	}
  PidlMgr_GetFolderText(this,pidlPath, lpszFolder, dwNameSize);

  //assemble the value name
  dwNameSize = PidlMgr_GetValueText(this,pidlValue, NULL, 0);
  lpszValueName = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize);
  if(!lpszValueName)
  { HeapFree(GetProcessHeap(),0,lpszFolder);
    return FALSE;
  }
  PidlMgr_GetValueText(this,pidlValue, lpszValueName, dwNameSize);

  /* fixme: we've got the path now do something with it*/
	
  HeapFree(GetProcessHeap(),0,lpszFolder);
  HeapFree(GetProcessHeap(),0,lpszValueName);

  TRACE(shell,"-- (%p)->(%p=%s 0x%08lx)\n",this,lpszOut,lpszOut,dwOutSize);

	return TRUE;
}

/**************************************************************************
 *   CPidlMgr::GetPidlPath()
 *  Create a string that includes the Drive name, the folder text and 
 *  the value text.
 */
DWORD PidlMgr_GetPidlPath(LPPIDLMGR this,
    LPCITEMIDLIST pidl, LPSTR lpszOut, DWORD dwOutSize)
{ LPSTR lpszTemp;
  WORD	len;

  TRACE(shell,"(%p)->(%p,%lu)\n",this,lpszOut,dwOutSize);

  if(!lpszOut)
  { return 0;
	}

  *lpszOut = 0;
  lpszTemp = lpszOut;

  dwOutSize -= PidlMgr_GetFolderText(this,pidl, lpszTemp, dwOutSize);

  //add a backslash if necessary
  len = strlen(lpszTemp);
  if (len && lpszTemp[len-1]!='\\')
	{ lpszTemp[len+0]='\\';
    lpszTemp[len+1]='\0';
		dwOutSize--;
  }

  lpszTemp = lpszOut + strlen(lpszOut);

  //add the value string
  PidlMgr_GetValueText(this,pidl, lpszTemp, dwOutSize);

  //remove the last backslash if necessary
  if(*(lpszOut + strlen(lpszOut) - 1) == '\\')
  { *(lpszOut + strlen(lpszOut) - 1) = 0;
  }

  TRACE(shell,"-- (%p)->(%p=%s,%lu)\n",this,lpszOut,lpszOut,dwOutSize);

  return strlen(lpszOut);

}
/**************************************************************************
 * PidlMgr_Concatenate()
 * Create a new PIDL by combining two existing PIDLs.
 */  
LPITEMIDLIST PidlMgr_Concatenate(
    LPPIDLMGR this,
		LPITEMIDLIST pidl1,
		LPITEMIDLIST pidl2)
{ LPITEMIDLIST   pidlNew;
  UINT32         cb1 = 0, cb2 = 0;

  TRACE(shell,"(%p)->(%p,%p)\n",this,pidl1,pidl2);

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

  if(!pidl1)
  { pidlNew = PidlMgr_Copy(this,pidl2);
    return pidlNew;
  }

  if(!pidl2)
  { pidlNew = PidlMgr_Copy(this,pidl1);
    return pidlNew;
  }

  cb1 = PidlMgr_GetSize(this,pidl1) - sizeof(ITEMIDLIST);
  cb2 = PidlMgr_GetSize(this,pidl2);

  pidlNew = (LPITEMIDLIST)HeapAlloc(GetProcessHeap(),0,cb1+cb2);

  if(pidlNew)
  { memcpy(pidlNew, pidl1, cb1);
    memcpy(((LPBYTE)pidlNew) + cb1, pidl2, cb2);
  }
  TRACE(shell,"-- (%p)-> (new pidl=%p)\n",this,pidlNew);
	return pidlNew;
}
/**************************************************************************
 *  PidlMgr_Create()
 *  Creates a new PIDL
 *  type = PT_DESKTOP | PT_DRIVE | PT_FOLDER | PT_VALUE
 *  pIn = data
 *  uInSize = size of data
 */

LPITEMIDLIST PidlMgr_Create(LPPIDLMGR this,PIDLTYPE type, LPVOID pIn, UINT16 uInSize)
{ LPITEMIDLIST   pidlOut=NULL;
  UINT16         uSize;
  LPITEMIDLIST   pidlTemp=NULL;
  LPPIDLDATA     pData;

  TRACE(shell,"(%p)->(%x %p %x)\n",this,type,pIn,uInSize);

  if ( type == PT_DESKTOP)
	{   pidlOut = (LPITEMIDLIST)HeapAlloc(GetProcessHeap(),0,sizeof(ITEMIDLIST));
  		memset(pidlOut, 0x00, sizeof(ITEMIDLIST));
	}

  if (! pIn)
	{ return NULL;
	}	
  uSize = sizeof(ITEMIDLIST) + (sizeof(PIDLTYPE)) + uInSize;

  /* Allocate the memory, adding an additional ITEMIDLIST for the NULL terminating 
  ID List. */
  pidlOut = (LPITEMIDLIST)HeapAlloc(GetProcessHeap(),0,uSize + sizeof(ITEMIDLIST));
	memset(pidlOut, 0xAA, uSize);
  pidlTemp = pidlOut;
  if(pidlOut)
  { pidlTemp->mkid.cb = uSize;
    pData = PidlMgr_GetDataPointer(this,pidlTemp);
    pData->type = type;
    switch(type)
    { case PT_MYCOMP:  memcpy(pData->szText, pIn, uInSize);
                       TRACE(shell,"- (%p)->create My Computer: %s\n",this,debugstr_a(pData->szText));
                       break;
			case PT_DRIVE:	 memcpy(pData->szText, pIn, uInSize);
                       TRACE(shell,"- (%p)->create Drive: %s\n",this,debugstr_a(pData->szText));
											 break;
      case PT_FOLDER:
      case PT_VALUE:   memcpy(pData->szText, pIn, uInSize);
                       TRACE(shell,"- (%p)->create Value: %s\n",this,debugstr_a(pData->szText));
											 break;
		  default:         FIXME(shell,"- (%p) wrong argument\n",this);
			                 break;
    }
   
    pidlTemp = PidlMgr_GetNextItem(this,pidlTemp);
    pidlTemp->mkid.cb = 0;
    pidlTemp->mkid.abID[0] = 0;
  }
	TRACE(shell,"-- (%p)->(pidl=%p)\n",this,pidlOut);
  return pidlOut;
}
/**************************************************************************
 *  PidlMgr_GetData(PIDLTYPE, LPCITEMIDLIST, LPVOID, UINT16)
 */
DWORD PidlMgr_GetData(
    LPPIDLMGR this,
		PIDLTYPE type, 
    LPCITEMIDLIST pidl,
		LPVOID pOut,
		UINT16 uOutSize)
{ LPPIDLDATA  pData;
  DWORD       dwReturn=0; 

	TRACE(shell,"(%p)->(%x %p %p %x)\n",this,type,pidl,pOut,uOutSize);
	
  if(!pidl)
  {  return 0;
	}

  pData = PidlMgr_GetDataPointer(this,pidl);

  //copy the data
  switch(type)
  { case PT_MYCOMP:  if(uOutSize < 1)
                       return 0;
                     if(PT_MYCOMP != pData->type)
                       return 0;
										 *(LPSTR)pOut = 0;	 
                     strncpy((LPSTR)pOut, "My Computer", uOutSize);
										 dwReturn = strlen((LPSTR)pOut);
                     break;

	 case PT_DRIVE:    if(uOutSize < 1)
                       return 0;
                     if(PT_DRIVE != pData->type)
                       return 0;
										 *(LPSTR)pOut = 0;	 
                     strncpy((LPSTR)pOut, pData->szText, uOutSize);
										 dwReturn = strlen((LPSTR)pOut);
                     break;

   case PT_FOLDER:
   case PT_VALUE: 
	 case PT_TEXT:     *(LPSTR)pOut = 0;
                     strncpy((LPSTR)pOut, pData->szText, uOutSize);
                     dwReturn = strlen((LPSTR)pOut);
                     break;
   default:     break;										 
  }
	TRACE(shell,"-- (%p)->(%p=%s 0x%08lx)\n",this,pOut,(char*)pOut,dwReturn);
  return dwReturn;
}


/**************************************************************************
 *  PidlMgr_GetDataPointer()
 */
LPPIDLDATA PidlMgr_GetDataPointer(LPPIDLMGR this,LPITEMIDLIST pidl)
{ if(!pidl)
  {  return NULL;
	}
	TRACE (shell,"(%p)->(%p)\n"	,this, pidl);
  return (LPPIDLDATA)(pidl->mkid.abID);
}

/**************************************************************************
 *  CPidlMgr_SeparatePathAndValue)
 *  Creates a separate path and value PIDL from a fully qualified PIDL.
 */
BOOL32 PidlMgr_SeparatePathAndValue(LPPIDLMGR this, 
   LPITEMIDLIST pidlFQ, LPITEMIDLIST *ppidlPath, LPITEMIDLIST *ppidlValue)
{ LPITEMIDLIST   pidlTemp;
	TRACE (shell,"(%p)->(pidl=%p pidl=%p pidl=%p)",this,pidlFQ,ppidlPath,ppidlValue);
  if(!pidlFQ)
  {  return FALSE;
	}

  *ppidlValue = PidlMgr_GetLastItem(this,pidlFQ);

  if(!PidlMgr_IsValue(this,*ppidlValue))
  { return FALSE;
	}

  *ppidlValue = PidlMgr_Copy(this,*ppidlValue);
  *ppidlPath = PidlMgr_Copy(this,pidlFQ);

  pidlTemp = PidlMgr_GetLastItem(this,*ppidlPath);
  pidlTemp->mkid.cb = 0;
  pidlTemp->mkid.abID[0] = 0;

  return TRUE;
}
