/*
 *	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, 980801>
 */

#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"
#include "winproc.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)
 *
 * gets a part of a string till the first backslash
 *
 * PARAMETERS
 *  pszNext [IN] string to get the element from
 *  pszOut  [IN] pointer to buffer whitch receives string
 *  dwOut   [IN] length of pszOut
 *
 *  RETURNS
 *    LPSTR pointer to first, not yet parsed char
 */
LPSTR GetNextElement(LPSTR pszNext,LPSTR pszOut,DWORD dwOut)
{ LPSTR   pszTail = pszNext;
  DWORD dwCopy;
  TRACE(shell,"(%s %p 0x%08lx)\n",debugstr_a(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",debugstr_a(pszNext),debugstr_a(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,%p)\n",this,pUnknown,xriid,ppObject);

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

	if (IsEqualIID(riid, &IID_IShellFolder))
  { pObj = (IUnknown *)IShellFolder_Constructor(NULL,NULL);
  } 
  else if (IsEqualIID(riid, &IID_IShellView))
  { pObj = (IUnknown *)IShellView_Constructor();
  } 
  else if (IsEqualIID(riid, &IID_IShellLink))
  { pObj = (IUnknown *)IShellLink_Constructor();
  } 
	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, BOOL32 fLock)
{ TRACE(shell,"%p->(0x%x), not implemented\n",this, fLock);
  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,debugstr_a(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);

  /* It is valid to leave pceltFetched NULL when celt is 1. Some of explorer's
     subsystems actually use it (and so may a third party browser)
   */
  if(pceltFetched)
    *pceltFetched = 0;

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

  for(i = 0; i < celt; i++)
  { if(!(this->mpCurrent))
    { hr =  S_FALSE;
      break;
    }
    temp = ILClone(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;
  DWORD dwDrivemap;
  CHAR  szDriveName[4];
  CHAR  szPath[MAX_PATH];
    
  TRACE(shell,"(%p)->(%s 0x%08lx) \n",this,debugstr_a(lpszPath),dwFlags);

  if (lpszPath && lpszPath[0]!='\0')
  { strcpy(szPath, lpszPath);
    PathAddBackslash(szPath);
    strcat(szPath,"*.*");
  }

  /*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 SHCONTF_FOLDERS (special) items\n",this);
  		//create the pidl for this item
      pidl = this->mpPidlMgr->lpvtbl->fnCreateMyComputer(this->mpPidlMgr);
      if(pidl)
      { if(!IEnumIDList_AddToEnumList(this, pidl))
        return FALSE;
      }
    }   
    else if (lpszPath[0]=='\0') /* enumerate the drives*/
    { TRACE (shell,"-- (%p)-> enumerate SHCONTF_FOLDERS (drives)\n",this);
      dwDrivemap = GetLogicalDrives();
      strcpy (szDriveName,"A:\\");
      while (szDriveName[0]<='Z')
      { if(dwDrivemap & 0x00000001L)
        { pidl = this->mpPidlMgr->lpvtbl->fnCreateDrive(this->mpPidlMgr,szDriveName );
      if(pidl)
      { if(!IEnumIDList_AddToEnumList(this, pidl))
          return FALSE;
      }
      }
        szDriveName[0]++;
        dwDrivemap = dwDrivemap >> 1;
     }   
    }
    
     else
    { TRACE (shell,"-- (%p)-> enumerate SHCONTF_FOLDERS of %s\n",this,debugstr_a(szPath));
      hFile = FindFirstFile32A(szPath,&stffile);
      if ( hFile != INVALID_HANDLE_VALUE32 )
      { do
        { if ( (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && strcmp (stffile.cFileName, ".") && strcmp (stffile.cFileName, ".."))
          { 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)
  { if(lpszPath)
    { TRACE (shell,"-- (%p)-> enumerate SHCONTF_NONFOLDERS of %s\n",this,debugstr_a(szPath));
      hFile = FindFirstFile32A(szPath,&stffile);
      if ( hFile != INVALID_HANDLE_VALUE32 )
      { do
    { if (! (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
          { pidl = this->mpPidlMgr->lpvtbl->fnCreateValue(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;
    SHFree(pDelete->pidl);
    SHFree(pDelete);
  }
  this->mpFirst = this->mpLast = this->mpCurrent = NULL;
  return TRUE;
}
/***********************************************************************
*   IShellView implementation
*/
static HRESULT WINAPI IShellView_QueryInterface(LPSHELLVIEW,REFIID riid, LPVOID *ppvObj);
static ULONG WINAPI IShellView_AddRef(LPSHELLVIEW) ;
static ULONG WINAPI IShellView_Release(LPSHELLVIEW);

    // *** IOleWindow methods ***
static HRESULT WINAPI IShellView_GetWindow(LPSHELLVIEW,HWND32 * lphwnd);
static HRESULT WINAPI IShellView_ContextSensitiveHelp(LPSHELLVIEW,BOOL32 fEnterMode);

    // *** IShellView methods ***
static HRESULT WINAPI IShellView_TranslateAccelerator(LPSHELLVIEW,LPMSG32 lpmsg);
static HRESULT WINAPI IShellView_EnableModeless(LPSHELLVIEW,BOOL32 fEnable);
static HRESULT WINAPI IShellView_UIActivate(LPSHELLVIEW,UINT32 uState);
static HRESULT WINAPI IShellView_Refresh(LPSHELLVIEW);
static HRESULT WINAPI IShellView_CreateViewWindow(LPSHELLVIEW, IShellView *lpPrevView,LPCFOLDERSETTINGS lpfs, IShellBrowser * psb,RECT32 * prcView, HWND32  *phWnd);
static HRESULT WINAPI IShellView_DestroyViewWindow(LPSHELLVIEW);
static HRESULT WINAPI IShellView_GetCurrentInfo(LPSHELLVIEW, LPFOLDERSETTINGS lpfs);
static HRESULT WINAPI IShellView_AddPropertySheetPages(LPSHELLVIEW, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam);
static HRESULT WINAPI IShellView_SaveViewState(LPSHELLVIEW);
static HRESULT WINAPI IShellView_SelectItem(LPSHELLVIEW, LPCITEMIDLIST pidlItem, UINT32 uFlags);
static HRESULT WINAPI IShellView_GetItemObject(LPSHELLVIEW, UINT32 uItem, REFIID riid,LPVOID *ppv);

static struct IShellView_VTable svvt = 
{ IShellView_QueryInterface,
  IShellView_AddRef,
  IShellView_Release,
  IShellView_GetWindow,
  IShellView_ContextSensitiveHelp,
  IShellView_TranslateAccelerator,
  IShellView_EnableModeless,
  IShellView_UIActivate,
  IShellView_Refresh,
  IShellView_CreateViewWindow,
  IShellView_DestroyViewWindow,
  IShellView_GetCurrentInfo,
  IShellView_AddPropertySheetPages,
  IShellView_SaveViewState,
  IShellView_SelectItem,
  IShellView_GetItemObject
};
/**************************************************************************
*  IShellView_Constructor
*/
LPSHELLVIEW IShellView_Constructor(LPSHELLFOLDER pFolder, LPCITEMIDLIST pidl)
{ LPSHELLVIEW sv;
  sv=(LPSHELLVIEW)HeapAlloc(GetProcessHeap(),0,sizeof(IShellView));
  sv->ref=1;
  sv->lpvtbl=&svvt;
  
  sv->mpidl = ILClone(pidl);

  sv->pSFParent = pFolder;
  if(sv->pSFParent)
    sv->pSFParent->lpvtbl->fnAddRef(sv->pSFParent);

  TRACE(shell,"(%p)->(%p pidl=%p)\n",sv, pFolder, pidl);
  return sv;
}
/**************************************************************************
*  ShellView_WndProc
*/
LRESULT CALLBACK ShellView_WndProc(HWND32 hWnd, UINT32 uMessage, WPARAM32 wParam, LPARAM lParam)
{ LPSHELLVIEW pThis = (LPSHELLVIEW)GetWindowLong32A(hWnd, GWL_USERDATA);
  LPCREATESTRUCT32A lpcs;

  FIXME(shell,"(hwnd=%x msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
    
  switch (uMessage)
  { case WM_NCCREATE:
      { TRACE(shell,"WM_NCCREATE\n");
        lpcs = (LPCREATESTRUCT32A)lParam;
        pThis = (LPSHELLVIEW)(lpcs->lpCreateParams);
        SetWindowLong32A(hWnd, GWL_USERDATA, (LONG)pThis);

        //set the window handle
        pThis->hWnd = hWnd;
      }
      break;
   
   case WM_SIZE:
      TRACE(shell,"WM_SIZE\n");
      return FALSE;
   
   case WM_CREATE:
      TRACE(shell,"WM_CREATE\n");
      return FALSE;
   
   case WM_SETFOCUS:
      TRACE(shell,"WM_SETFOCUS\n");   
      return FALSE;
   
   case WM_KILLFOCUS:
      TRACE(shell,"WM_KILLFOCUS\n");
      return FALSE;

   case WM_ACTIVATE:
      TRACE(shell,"WM_ACTIVATE\n");
      return FALSE;
   
   case WM_COMMAND:
      TRACE(shell,"WM_COMMAND\n");
      return FALSE;
   
   case WM_INITMENUPOPUP:
      TRACE(shell,"WM_INITMENUPOPUP\n");
      return FALSE;
   
   case WM_NOTIFY:
      TRACE(shell,"WM_NOTIFY\n");
      return FALSE;
   
/*   case WM_SETTINGCHANGE:
      return FALSE;*/
  }

  return DefWindowProc32A (hWnd, uMessage, wParam, lParam);
}


/**************************************************************************
*  IShellView::QueryInterface
*/
static HRESULT WINAPI IShellView_QueryInterface(LPSHELLVIEW 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_IShellView))  /*IShellView*/
  { *ppvObj = (IShellView*)this;
  }   

  if(*ppvObj)
  { (*(LPSHELLVIEW*)ppvObj)->lpvtbl->fnAddRef(this);      
    TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
    return S_OK;
  }
  TRACE(shell,"-- Interface: E_NOINTERFACE\n");
  return E_NOINTERFACE;
}   
/**************************************************************************
*  IShellView::AddRef
*/
static ULONG WINAPI IShellView_AddRef(LPSHELLVIEW this)
{ TRACE(shell,"(%p)->(count=%lu)\n",this,(this->ref)+1);
  return ++(this->ref);
}
/**************************************************************************
*  IShellView::Release
*/
static ULONG WINAPI IShellView_Release(LPSHELLVIEW this)
{ TRACE(shell,"(%p)->()\n",this);
  if (!--(this->ref)) 
  { TRACE(shell," destroying IEnumIDList(%p)\n",this);

    if(this->pSFParent)
       this->pSFParent->lpvtbl->fnRelease(this->pSFParent);

    HeapFree(GetProcessHeap(),0,this);
    return 0;
  }
  return this->ref;
}
/**************************************************************************
*  IShellView::GetWindow
*/
static HRESULT WINAPI IShellView_GetWindow(LPSHELLVIEW this,HWND32 * phWnd)
{ TRACE(shell,"(%p) stub\n",this);
 *phWnd = this->hWnd;

 return S_OK;
}
static HRESULT WINAPI IShellView_ContextSensitiveHelp(LPSHELLVIEW this,BOOL32 fEnterMode)
{ FIXME(shell,"(%p) stub\n",this);
  return E_NOTIMPL;
}
static HRESULT WINAPI IShellView_TranslateAccelerator(LPSHELLVIEW this,LPMSG32 lpmsg)
{ FIXME(shell,"(%p)->(%p) stub\n",this,lpmsg);
  return E_NOTIMPL;
}
static HRESULT WINAPI IShellView_EnableModeless(LPSHELLVIEW this,BOOL32 fEnable)
{ FIXME(shell,"(%p) stub\n",this);
  return E_NOTIMPL;
}
static HRESULT WINAPI IShellView_UIActivate(LPSHELLVIEW this,UINT32 uState)
{ FIXME(shell,"(%p) stub\n",this);
  return E_NOTIMPL;
}
static HRESULT WINAPI IShellView_Refresh(LPSHELLVIEW this)
{ FIXME(shell,"(%p) stub\n",this);
  return S_OK;
}
static HRESULT WINAPI IShellView_CreateViewWindow(LPSHELLVIEW this, IShellView *lpPrevView,
                     LPCFOLDERSETTINGS lpfs, IShellBrowser * psb,RECT32 * prcView, HWND32  *phWnd)
{  WNDCLASS32A wc;
   *phWnd = 0;

   TRACE(shell,"(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",this, lpPrevView,lpfs, psb, prcView, phWnd);

//if our window class has not been registered, then do so
  if(!GetClassInfo32A(shell32_hInstance, SV_CLASS_NAME, &wc))
  { ZeroMemory(&wc, sizeof(wc));
    wc.style          = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc    = (WNDPROC32) ShellView_WndProc;
    wc.cbClsExtra     = 0;
    wc.cbWndExtra     = 0;
    wc.hInstance      = shell32_hInstance;
    wc.hIcon          = 0;
    wc.hCursor        = LoadCursor32A (0, IDC_ARROW32A);
    wc.hbrBackground  = (HBRUSH32)(COLOR_WINDOW + 1);
    wc.lpszMenuName   = NULL;
    wc.lpszClassName  = SV_CLASS_NAME;
   
    if(!RegisterClass32A(&wc))
      return E_FAIL;
   }
   //set up the member variables
   this->pShellBrowser = psb;
   this->FolderSettings = *lpfs;

   //get our parent window
   this->pShellBrowser->lpvtbl->fnGetWindow(this->pShellBrowser, &(this->hWndParent));

   *phWnd = CreateWindowEx32A(0, SV_CLASS_NAME, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
                           prcView->left, prcView->top, prcView->right - prcView->left, prcView->bottom - prcView->top,
                           this->hWndParent, 0, shell32_hInstance, (LPVOID)this);
                           
   if(!*phWnd)
     return E_FAIL;

   this->pShellBrowser->lpvtbl->fnAddRef(this->pShellBrowser);

   return S_OK;
}

static HRESULT WINAPI IShellView_DestroyViewWindow(LPSHELLVIEW this)
{ FIXME(shell,"(%p) stub\n",this);

  this->pShellBrowser->lpvtbl->fnRelease(this->pShellBrowser);

  return S_OK;
}
static HRESULT WINAPI IShellView_GetCurrentInfo(LPSHELLVIEW this, LPFOLDERSETTINGS lpfs)
{ FIXME(shell,"(%p)->(%p)stub\n",this, lpfs);

  *lpfs = this->FolderSettings;
  return S_OK;
}
static HRESULT WINAPI IShellView_AddPropertySheetPages(LPSHELLVIEW this, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
{ FIXME(shell,"(%p) stub\n",this);
  return E_NOTIMPL;
}
static HRESULT WINAPI IShellView_SaveViewState(LPSHELLVIEW this)
{ FIXME(shell,"(%p) stub\n",this);
  return S_OK;
}
static HRESULT WINAPI IShellView_SelectItem(LPSHELLVIEW this, LPCITEMIDLIST pidlItem, UINT32 uFlags)
{ FIXME(shell,"(%p)->(pidl=%p, 0x%08x) stub\n",this, pidlItem, uFlags);
  return E_NOTIMPL;
}
static HRESULT WINAPI IShellView_GetItemObject(LPSHELLVIEW this, UINT32 uItem, REFIID riid,LPVOID *ppvOut)
{ char    xriid[50];
  WINE_StringFromCLSID((LPCLSID)riid,xriid);

  FIXME(shell,"(%p)->(0x%08x,\n\t%s, %p)stub\n",this, uItem, xriid, ppvOut);

  *ppvOut = NULL;
  return E_NOTIMPL;
}

/***********************************************************************
*   IShellFolder implementation
*/
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_ParseDisplayName,
	IShellFolder_EnumObjects,
	IShellFolder_BindToObject,
  IShellFolder_BindToStorage,
  IShellFolder_CompareIDs,
	IShellFolder_CreateViewObject,
	IShellFolder_GetAttributesOf,
  IShellFolder_GetUIObjectOf,
  IShellFolder_GetDisplayNameOf,
  IShellFolder_SetNameOf
  /*    IShellFolder_Initialize*/
};
/**************************************************************************
*	  IShellFolder_Constructor
*/

LPSHELLFOLDER IShellFolder_Constructor(LPSHELLFOLDER pParent,LPITEMIDLIST pidl) 
{ LPSHELLFOLDER    sf;
	DWORD dwSize=0;
  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 = ILClone(pidl);
	sf->mpidlNSRoot = NULL;
	
  if(sf->mpidl)        /* do we have a pidl?*/
  { 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 = SHAlloc(dwSize);
    if(sf->mlpszFolder)
    { *(sf->mlpszFolder)=0x00;
      if(sf->mpSFParent->mlpszFolder)
      {  strcpy(sf->mlpszFolder, sf->mpSFParent->mlpszFolder);
         PathAddBackslash (sf->mlpszFolder);
      }
      sf->pPidlMgr->lpvtbl->fnGetFolderText(sf->pPidlMgr, sf->mpidl, sf->mlpszFolder+strlen(sf->mlpszFolder), dwSize-strlen(sf->mlpszFolder));
    }
  }
	
  TRACE(shell,"-- (%p)->(%p,%p,parent=%s)\n",sf,pParent, pidl, debugstr_a(sf->mlpszFolder));
	return sf;
}
/**************************************************************************
*  IShellFolder::QueryInterface
* PARAMETERS
*  REFIID riid,        //[in ] Requested InterfaceID
*  LPVOID* ppvObject)  //[out] Interface* to hold the result
*/
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);
		}
    if (this->pPidlMgr)
    { PidlMgr_Destructor(this->pPidlMgr);
    }
    if(this->mpidlNSRoot)
    { SHFree(this->mpidlNSRoot);
    }
    if(this->mpidl)
    { SHFree(this->mpidl);
    }
    if(this->mlpszFolder)
    { SHFree(this->mlpszFolder);
    }

		HeapFree(GetProcessHeap(),0,this);

		return 0;
	}
	return this->ref;
}
/**************************************************************************
*		IShellFolder_ParseDisplayName
* PARAMETERS
*  HWND          hwndOwner,      //[in ] Parent window for any message's
*  LPBC          pbc,            //[in ] reserved
*  LPOLESTR      lpszDisplayName,//[in ] "Unicode" displayname.
*  ULONG*        pchEaten,       //[out] (unicode) characters processed
*  LPITEMIDLIST* ppidl,          //[out] complex pidl to item
*  ULONG*        pdwAttributes   //[out] items attributes
*
* FIXME: 
*    pdwAttributes: not used
*/
static HRESULT WINAPI IShellFolder_ParseDisplayName(
	LPSHELLFOLDER this,
	HWND32 hwndOwner,
	LPBC pbcReserved,
    LPOLESTR32 lpszDisplayName,
    DWORD *pchEaten,
    LPITEMIDLIST *ppidl,
	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,2);
			  pidlFull->mkid.cb = 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 = ILCombine(pidlFull,pidlTemp);
        SHFree(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 = ILCombine(pidlFull,pidlTemp);
            SHFree(pidlOld);
          }
          hr = S_OK;
        }
      }
		}
  }
	HeapFree(GetProcessHeap(),0,pszTemp);
  *ppidl = pidlFull;
  return hr;
}

/**************************************************************************
*		IShellFolder_EnumObjects
* PARAMETERS
*  HWND          hwndOwner,    //[in ] Parent Window
*  DWORD         grfFlags,     //[in ] SHCONTF enumeration mask
*  LPENUMIDLIST* ppenumIDList  //[out] IEnumIDList interface
*/
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)
  { SHFree(this->mpidlNSRoot);
    this->mpidlNSRoot = NULL;
  }
  this->mpidlNSRoot=ILClone(pidl);
  return S_OK;
}

/**************************************************************************
*		IShellFolder_BindToObject
* PARAMETERS
*  LPCITEMIDLIST pidl,       //[in ] complex pidl to open
*  LPBC          pbc,        //[in ] reserved
*  REFIID        riid,       //[in ] Initial Interface
*  LPVOID*       ppvObject   //[out] Interface*
*/
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
* PARAMETERS
*  LPCITEMIDLIST pidl,       //[in ] complex pidl to store
*  LPBC          pbc,        //[in ] reserved
*  REFIID        riid,       //[in ] Initial storage interface 
*  LPVOID*       ppvObject   //[out] Interface* returned
*/
static HRESULT WINAPI IShellFolder_BindToStorage(
  	LPSHELLFOLDER this,
    LPCITEMIDLIST pidl, /*simple/complex 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
*
* PARMETERS
*  LPARAM        lParam, //[in ] Column?
*  LPCITEMIDLIST pidl1,  //[in ] simple pidl
*  LPCITEMIDLIST pidl2)  //[in ] simple pidl
* FIXME
*  we have to handle simple pidl's only
*/
static HRESULT WINAPI  IShellFolder_CompareIDs(
  	LPSHELLFOLDER this,
		LPARAM lParam, 
    LPCITEMIDLIST pidl1, /*simple pidl*/
    LPCITEMIDLIST pidl2) /*simple pidl*/
{ CHAR szString1[MAX_PATH] = "";
  CHAR szString2[MAX_PATH] = "";
  int   nReturn;
  LPCITEMIDLIST  pidlTemp1 = pidl1, pidlTemp2 = pidl2;

  TRACE(shell,"(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\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
* Creates an View Object representing the ShellFolder
*  IShellView / IShellBrowser / IContextMenu
*
* PARAMETERS
*  HWND    hwndOwner,  // Handle of owner window
*  REFIID  riid,       // Requested initial interface
*  LPVOID* ppvObject)  // Resultant interface*
*
* NOTES
*  the same as SHCreateShellFolderViewEx ???
*/
static HRESULT WINAPI IShellFolder_CreateViewObject(
	LPSHELLFOLDER this,
	HWND32 hwndOwner,
	REFIID riid,
	LPVOID *ppvOut)
{ LPSHELLVIEW pShellView;
  char    xriid[50];
  HRESULT       hr;

	WINE_StringFromCLSID(riid,xriid);
  TRACE(shell,"(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",this,hwndOwner,xriid,ppvOut);
	
	*ppvOut = NULL;

  pShellView = IShellView_Constructor(this, this->mpidl);
  if(!pShellView)
    return E_OUTOFMEMORY;
  hr = pShellView->lpvtbl->fnQueryInterface(pShellView, riid, ppvOut);
  pShellView->lpvtbl->fnRelease(pShellView);
  TRACE(shell,"-- (%p)->(interface=%p)\n",this, ppvOut);
  return hr; 
}

/**************************************************************************
*  IShellFolder_GetAttributesOf
*
* PARAMETERS
*  UINT            cidl,     //[in ] num elements in pidl array
+  LPCITEMIDLIST*  apidl,    //[in ] simple pidl array 
*  ULONG*          rgfInOut) //[out] result array  
*
* FIXME: quick hack
*  Note: rgfInOut is documented as being an array of ULONGS.
*  This does not seem to be the case. Testing this function using the shell to 
*  call it with cidl > 1 (by deleting multiple items) reveals that the shell
*  passes ONE element in the array and writing to further elements will
*  cause the shell to fail later.
*/
static HRESULT WINAPI IShellFolder_GetAttributesOf(
	LPSHELLFOLDER this,
	UINT32 cidl,
    LPCITEMIDLIST *apidl, /*simple pidl's*/
	DWORD *rgfInOut)
{ LPCITEMIDLIST * pidltemp;
  DWORD i;
  TRACE(shell,"(%p)->(%d,%p,%p)\n",this,cidl,apidl,rgfInOut);

  pidltemp=apidl;
  *rgfInOut = 0x00;
  i=cidl;
  if ((! cidl )| (!apidl) | (!rgfInOut))
    return E_INVALIDARG;
  
  do
  { if (*pidltemp)
    { if (this->pPidlMgr->lpvtbl->fnIsDesktop(this->pPidlMgr, *pidltemp))
      { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR);
      }
      else if (this->pPidlMgr->lpvtbl->fnIsMyComputer(this->pPidlMgr, *pidltemp))
      { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER);
      }
      else if (this->pPidlMgr->lpvtbl->fnIsDrive(this->pPidlMgr, *pidltemp))
      { *rgfInOut |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR | SFGAO_FILESYSTEM);
      }
      else if (this->pPidlMgr->lpvtbl->fnIsFolder(this->pPidlMgr, *pidltemp))
      { *rgfInOut |= (SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER);
      }
      else if (this->pPidlMgr->lpvtbl->fnIsValue(this->pPidlMgr, *pidltemp))
      { *rgfInOut |= (SFGAO_FILESYSTEM);
      }
    }
    pidltemp++;
    cidl--;
  } while (cidl > 0 && *pidltemp);

  return S_OK;
}
/**************************************************************************
*  IShellFolder_GetUIObjectOf
*
* PARAMETERS
*  HWND           hwndOwner, //[in ] Parent window for any output
*  UINT           cidl,      //[in ] array size
*  LPCITEMIDLIST* apidl,     //[in ] simple pidl array
*  REFIID         riid,      //[in ] Requested Interface
*  UINT*          prgfInOut, //[   ] reserved 
*  LPVOID*        ppvObject) //[out] Resulting Interface
*
* NOTES
*  This function gets asked to return "view objects" for one or more (multiple select)
*  items:
*  The viewobject typically is an COM object with one of the following interfaces:
*  IExtractIcon,IDataObject,IContextMenu
*  In order to support icon positions in the default Listview your DataObject
*  must implement the SetData method (in addition to GetData :) - the shell passes
*  a barely documented "Icon positions" structure to SetData when the drag starts,
*  and GetData's it if the drop is in another explorer window that needs the positions.
*/
static HRESULT WINAPI IShellFolder_GetUIObjectOf(
	LPSHELLFOLDER this,
	HWND32 hwndOwner,
	UINT32 cidl, 
  LPCITEMIDLIST * apidl, /* simple pidl's*/
  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
*  Retrieves the display name for the specified file object or subfolder
*
* PARAMETERS
*  LPCITEMIDLIST pidl,    //[in ] complex pidl to item
*  DWORD         dwFlags, //[in ] SHGNO formatting flags
*  LPSTRRET      lpName)  //[out] Returned display name
*
* 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, /* simple/complex 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);

  if (!pidl)
  {  return E_OUTOFMEMORY;
  } 

  szSpecial[0]=0x00; 
  szDrive[0]=0x00;

  /* 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
  { if (this->pPidlMgr->lpvtbl->fnIsMyComputer(this->pPidlMgr, pidl))
    { this->pPidlMgr->lpvtbl->fnGetItemText(this->pPidlMgr, pidl, szSpecial, MAX_PATH);
    }
	  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]=0x00;
				}
        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*/
          szText[0]=0x00;
				  if (this->mlpszFolder && strlen (this->mlpszFolder))
          { if (strcmp(this->mlpszFolder,"My Computer"))
  			  { strcpy (szText,this->mlpszFolder);
  			    PathAddBackslash (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
*  Changes the name of a file object or subfolder, possibly changing its item
*  identifier in the process.
*
* PARAMETERS
*  HWND          hwndOwner,  //[in ] Owner window for output
*  LPCITEMIDLIST pidl,       //[in ] simple pidl of item to change
*  LPCOLESTR     lpszName,   //[in ] the items new display name
*  DWORD         dwFlags,    //[in ] SHGNO formatting flags
*  LPITEMIDLIST* ppidlOut)   //[out] simple pidl returned
*/
static HRESULT WINAPI IShellFolder_SetNameOf(
  	LPSHELLFOLDER this,
		HWND32 hwndOwner, 
    LPCITEMIDLIST pidl, /*simple 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 Implementation
*/
static HRESULT WINAPI IShellLink_QueryInterface(LPSHELLLINK,REFIID,LPVOID*);
static ULONG WINAPI IShellLink_AddRef(LPSHELLLINK);
static ULONG WINAPI IShellLink_Release(LPSHELLLINK);

/**************************************************************************
*	  IShellLink_VTable
*/
static struct IShellLink_VTable slvt = {
  IShellLink_QueryInterface,
  IShellLink_AddRef,
  IShellLink_Release,
    (void *)0xcafe0004,
    (void *)0xcafe0005,
    (void *)0xcafe0006,
    (void *)0xcafe0007,
    (void *)0xcafe0008,
    (void *)0xcafe0009,
    (void *)0xcafe0010,
    (void *)0xcafe0011,
    (void *)0xcafe0012,
    (void *)0xcafe0013,
    (void *)0xcafe0014,
    (void *)0xcafe0015,
    (void *)0xcafe0016,
    (void *)0xcafe0017,
    (void *)0xcafe0018,
    (void *)0xcafe0019,
    (void *)0xcafe0020,
    (void *)0xcafe0021
};

/**************************************************************************
 *	  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;
}

/**************************************************************************
 *  IShellLink::QueryInterface
 */
static HRESULT WINAPI IShellLink_QueryInterface(
  LPSHELLLINK 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_IShellLink))  /*IShellLink*/
  {    *ppvObj = (LPSHELLLINK)this;
  }   

  if(*ppvObj)
  { (*(LPSHELLLINK*)ppvObj)->lpvtbl->fnAddRef(this);      
    TRACE(shell,"-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
    return S_OK;
  }
    TRACE(shell,"-- Interface: E_NOINTERFACE\n");
  return E_NOINTERFACE;
}  
/******************************************************************************
 * IShellLink_AddRef
 */
static ULONG WINAPI IShellLink_AddRef(LPSHELLLINK this)
{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
    return ++(this->ref);
}
/******************************************************************************
 * IClassFactory_Release
 */
static ULONG WINAPI IShellLink_Release(LPSHELLLINK this)
{ TRACE(shell,"(%p)->(count=%lu)\n",this,this->ref);
  if (!--(this->ref)) 
  { TRACE(shell,"-- destroying IShellLink(%p)\n",this);
    HeapFree(GetProcessHeap(),0,this);
    return 0;
  }
  return this->ref;
}


/**************************************************************************
*	  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);
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_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_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_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_CreateMyComputer()
 *  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", strlen ("My Computer")+1);
}
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_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 (pidlTemp && 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);

  if (! pidl)
    return FALSE;

  return (  pidl->mkid.cb == 0x00 );
}

BOOL32 PidlMgr_IsMyComputer(LPPIDLMGR this,LPCITEMIDLIST pidl)
{ LPPIDLDATA  pData;
  TRACE(shell,"%p->(%p)\n",this,pidl);

  if (! pidl)
    return FALSE;

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

  if (! pidl)
    return FALSE;

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

  if (! pidl)
    return FALSE;

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

  if (! pidl)
    return FALSE;

  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);
    TRACE(shell,"-- (%p)->skip My Computer\n",this);
	}
  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 || !pidlPath || !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_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 = SHAlloc(2);
      pidlOut->mkid.cb=0x0000;
      return pidlOut;
	}

  if (! pIn)
	{ return NULL;
	}	

  uSize = 2 + (sizeof(PIDLTYPE)) + uInSize + 2;  /* cb + PIDLTYPE + uInSize +2 */
  pidlOut = SHAlloc(uSize);
  pidlTemp = pidlOut;
  if(pidlOut)
  { pidlTemp->mkid.cb = uSize - 2;
    pData =(LPPIDLDATA) &(pidlTemp->mkid.abID[0]);
    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 = 0x00;
  }
  TRACE(shell,"-- (%p)->(pidl=%p, size=%u)\n",this,pidlOut,uSize-2);
  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 = ILClone(*ppidlValue);
  *ppidlPath = ILClone(pidlFQ);

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

  return TRUE;
}
