1791 lines
53 KiB
C
1791 lines
53 KiB
C
/*
|
|
* 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;
|
|
}
|