847 lines
22 KiB
C
847 lines
22 KiB
C
|
/*
|
||
|
* pidl Handling
|
||
|
*
|
||
|
* 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 "shell.h"
|
||
|
#include "winerror.h"
|
||
|
#include "winnls.h"
|
||
|
#include "winproc.h"
|
||
|
#include "commctrl.h"
|
||
|
#include "shell32_main.h"
|
||
|
|
||
|
#include "pidl.h"
|
||
|
|
||
|
void pdump (LPCITEMIDLIST pidl)
|
||
|
{ DWORD type;
|
||
|
CHAR * szData;
|
||
|
LPITEMIDLIST pidltemp = pidl;
|
||
|
TRACE(pidl,"---------- pidl=%p \n", pidl);
|
||
|
do
|
||
|
{ szData = ((LPPIDLDATA )(pidltemp->mkid.abID))->szText;
|
||
|
type = ((LPPIDLDATA )(pidltemp->mkid.abID))->type;
|
||
|
TRACE(pidl,"---- pidl=%p size=%u type=%lx %s\n",pidltemp, pidltemp->mkid.cb,type,debugstr_a(szData));
|
||
|
pidltemp = (LPITEMIDLIST)(((BYTE*)pidltemp)+pidltemp->mkid.cb);
|
||
|
} while (pidltemp->mkid.cb);
|
||
|
}
|
||
|
/*************************************************************************
|
||
|
* ILGetDisplayName [SHELL32.15]
|
||
|
*/
|
||
|
BOOL32 WINAPI ILGetDisplayName(LPCITEMIDLIST iil,LPSTR path)
|
||
|
{ FIXME(pidl,"(%p,%p),stub, return e:!\n",iil,path);
|
||
|
strcpy(path,"e:\\");
|
||
|
return TRUE;
|
||
|
}
|
||
|
/*************************************************************************
|
||
|
* ILFindLastID [SHELL32.16]
|
||
|
*/
|
||
|
LPSHITEMID WINAPI ILFindLastID(LPITEMIDLIST iil)
|
||
|
{ LPSHITEMID lastsii,sii;
|
||
|
|
||
|
TRACE(pidl,"%p\n",iil);
|
||
|
if (!iil)
|
||
|
{ return NULL;
|
||
|
}
|
||
|
sii = &(iil->mkid);
|
||
|
lastsii = sii;
|
||
|
while (sii->cb)
|
||
|
{ lastsii = sii;
|
||
|
sii = (LPSHITEMID)(((char*)sii)+sii->cb);
|
||
|
}
|
||
|
return lastsii;
|
||
|
}
|
||
|
/*************************************************************************
|
||
|
* ILRemoveLastID [SHELL32.17]
|
||
|
* NOTES
|
||
|
* Removes the last item
|
||
|
*/
|
||
|
BOOL32 WINAPI ILRemoveLastID(LPCITEMIDLIST pidl)
|
||
|
{ LPCITEMIDLIST xpidl;
|
||
|
|
||
|
TRACE(shell,"pidl=%p\n",pidl);
|
||
|
if (!pidl || !pidl->mkid.cb)
|
||
|
return 0;
|
||
|
ILFindLastID(pidl)->cb = 0;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
* ILClone [SHELL32.18]
|
||
|
*
|
||
|
* NOTES
|
||
|
* dupicate an idlist
|
||
|
*/
|
||
|
LPITEMIDLIST WINAPI ILClone (LPCITEMIDLIST pidl)
|
||
|
{ DWORD len;
|
||
|
LPITEMIDLIST newpidl;
|
||
|
|
||
|
TRACE(pidl,"%p\n",pidl);
|
||
|
|
||
|
if (!pidl)
|
||
|
return NULL;
|
||
|
|
||
|
len = ILGetSize(pidl);
|
||
|
newpidl = (LPITEMIDLIST)SHAlloc(len);
|
||
|
if (newpidl)
|
||
|
memcpy(newpidl,pidl,len);
|
||
|
return newpidl;
|
||
|
}
|
||
|
/*************************************************************************
|
||
|
* ILCloneFirst [SHELL32.19]
|
||
|
*
|
||
|
* NOTES
|
||
|
* duplicates the first idlist of a complex pidl
|
||
|
*/
|
||
|
LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST pidl)
|
||
|
{ FIXME(pidl,"pidl=%p\n",pidl);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
* ILCombine [SHELL32.25]
|
||
|
*
|
||
|
* NOTES
|
||
|
* Concatenates two complex idlists.
|
||
|
* The pidl is the first one, pidlsub the next one
|
||
|
* Does not destroy the passed in idlists!
|
||
|
*/
|
||
|
LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2)
|
||
|
{ DWORD len1,len2;
|
||
|
LPITEMIDLIST pidlNew;
|
||
|
|
||
|
TRACE(pidl,"pidl=%p pidl=%p\n",pidl1,pidl2);
|
||
|
|
||
|
if(!pidl1 && !pidl2)
|
||
|
{ return NULL;
|
||
|
}
|
||
|
|
||
|
if(!pidl1)
|
||
|
{ pidlNew = ILClone(pidl2);
|
||
|
return pidlNew;
|
||
|
}
|
||
|
|
||
|
if(!pidl2)
|
||
|
{ pidlNew = ILClone(pidl1);
|
||
|
return pidlNew;
|
||
|
}
|
||
|
|
||
|
len1 = ILGetSize(pidl1)-2;
|
||
|
len2 = ILGetSize(pidl2);
|
||
|
pidlNew = SHAlloc(len1+len2);
|
||
|
|
||
|
if (pidlNew)
|
||
|
{ memcpy(pidlNew,pidl1,len1);
|
||
|
memcpy(((BYTE *)pidlNew)+len1,pidl2,len2);
|
||
|
}
|
||
|
|
||
|
/* TRACE(pidl,"--new pidl=%p\n",pidlNew);*/
|
||
|
return pidlNew;
|
||
|
}
|
||
|
/*************************************************************************
|
||
|
* ILGetSize [SHELL32.152]
|
||
|
* gets the byte size of an idlist including zero terminator (pidl)
|
||
|
*
|
||
|
* PARAMETERS
|
||
|
* pidl ITEMIDLIST
|
||
|
*
|
||
|
* RETURNS
|
||
|
* size of pidl
|
||
|
*
|
||
|
* NOTES
|
||
|
* exported by ordinal
|
||
|
*/
|
||
|
DWORD WINAPI ILGetSize(LPITEMIDLIST pidl)
|
||
|
{ LPSHITEMID si = &(pidl->mkid);
|
||
|
DWORD len=0;
|
||
|
|
||
|
TRACE(pidl,"pidl=%p\n",pidl);
|
||
|
|
||
|
if (pidl)
|
||
|
{ while (si->cb)
|
||
|
{ len += si->cb;
|
||
|
si = (LPSHITEMID)(((LPBYTE)si)+si->cb);
|
||
|
}
|
||
|
len += 2;
|
||
|
}
|
||
|
/* TRACE(pidl,"-- size=%lu\n",len);*/
|
||
|
return len;
|
||
|
}
|
||
|
/*************************************************************************
|
||
|
* ILGetNext [SHELL32.153]
|
||
|
* gets the next simple pidl ot of a complex pidl
|
||
|
*
|
||
|
* PARAMETERS
|
||
|
* pidl ITEMIDLIST
|
||
|
*
|
||
|
* RETURNS
|
||
|
* pointer to next element
|
||
|
*
|
||
|
*/
|
||
|
LPITEMIDLIST WINAPI ILGetNext(LPITEMIDLIST pidl)
|
||
|
{ LPITEMIDLIST nextpidl;
|
||
|
|
||
|
TRACE(pidl,"(pidl=%p)\n",pidl);
|
||
|
if(pidl)
|
||
|
{ nextpidl = (LPITEMIDLIST)(LPBYTE)(((LPBYTE)pidl) + pidl->mkid.cb);
|
||
|
return nextpidl;
|
||
|
}
|
||
|
else
|
||
|
{ return (NULL);
|
||
|
}
|
||
|
}
|
||
|
/*************************************************************************
|
||
|
* ILAppend [SHELL32.154]
|
||
|
*
|
||
|
* NOTES
|
||
|
* Adds the single item to the idlist indicated by pidl.
|
||
|
* if bEnd is 0, adds the item to the front of the list,
|
||
|
* otherwise adds the item to the end.
|
||
|
* Destroys the passed in idlist!
|
||
|
*/
|
||
|
LPITEMIDLIST WINAPI ILAppend(LPITEMIDLIST pidl,LPCITEMIDLIST item,BOOL32 bEnd)
|
||
|
{ TRACE(pidl,"(pidl=%p,pidl=%p,%08u)\n",pidl,item,bEnd);
|
||
|
return NULL;
|
||
|
}
|
||
|
/*************************************************************************
|
||
|
* ILFree [SHELL32.155]
|
||
|
*
|
||
|
* NOTES
|
||
|
* free_check_ptr - frees memory (if not NULL)
|
||
|
* allocated by SHMalloc allocator
|
||
|
* exported by ordinal
|
||
|
*/
|
||
|
DWORD WINAPI ILFree(LPVOID pidl)
|
||
|
{ TRACE(pidl,"(pidl=0x%08lx)\n",(DWORD)pidl);
|
||
|
if (!pidl)
|
||
|
return 0;
|
||
|
return SHFree(pidl);
|
||
|
}
|
||
|
|
||
|
/**************************************************************************
|
||
|
* INTERNAL CLASS pidlmgr
|
||
|
*/
|
||
|
|
||
|
static struct PidlMgr_VTable pmgrvt = {
|
||
|
PidlMgr_CreateDesktop,
|
||
|
PidlMgr_CreateMyComputer,
|
||
|
PidlMgr_CreateDrive,
|
||
|
PidlMgr_CreateFolder,
|
||
|
PidlMgr_CreateValue,
|
||
|
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(pidl,"(%p)->()\n",pmgr);
|
||
|
/** FIXMEDllRefCount++;*/
|
||
|
return pmgr;
|
||
|
}
|
||
|
/**************************************************************************
|
||
|
* PidlMgr_Destructor
|
||
|
*/
|
||
|
void PidlMgr_Destructor(LPPIDLMGR this)
|
||
|
{ HeapFree(GetProcessHeap(),0,this);
|
||
|
TRACE(pidl,"(%p)->()\n",this);
|
||
|
/** FIXMEDllRefCount--;*/
|
||
|
}
|
||
|
|
||
|
/**************************************************************************
|
||
|
* PidlMgr_CreateDesktop()
|
||
|
* PidlMgr_CreateMyComputer()
|
||
|
* PidlMgr_CreateDrive()
|
||
|
* PidlMgr_CreateFolder()
|
||
|
* PidlMgr_CreateValue()
|
||
|
*/
|
||
|
LPITEMIDLIST PidlMgr_CreateDesktop(LPPIDLMGR this)
|
||
|
{ TRACE(pidl,"(%p)->()\n",this);
|
||
|
return PidlMgr_Create(this,PT_DESKTOP, NULL, 0);
|
||
|
}
|
||
|
LPITEMIDLIST PidlMgr_CreateMyComputer(LPPIDLMGR this)
|
||
|
{ TRACE(pidl,"(%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(pidl,"(%p)->(%s)\n",this,sTemp);
|
||
|
return PidlMgr_Create(this,PT_DRIVE,(LPVOID)&sTemp[0],4);
|
||
|
}
|
||
|
LPITEMIDLIST PidlMgr_CreateFolder(LPPIDLMGR this, LPCSTR lpszNew)
|
||
|
{ TRACE(pidl,"(%p)->(%s)\n",this,lpszNew);
|
||
|
return PidlMgr_Create(this,PT_FOLDER, (LPVOID)lpszNew, strlen(lpszNew)+1);
|
||
|
}
|
||
|
LPITEMIDLIST PidlMgr_CreateValue(LPPIDLMGR this,LPCSTR lpszNew)
|
||
|
{ TRACE(pidl,"(%p)->(%s)\n",this,lpszNew);
|
||
|
return PidlMgr_Create(this,PT_VALUE, (LPVOID)lpszNew, strlen(lpszNew)+1);
|
||
|
}
|
||
|
|
||
|
/**************************************************************************
|
||
|
* PidlMgr_GetDesktop()
|
||
|
*
|
||
|
* FIXME: quick hack
|
||
|
*/
|
||
|
BOOL32 PidlMgr_GetDesktop(LPPIDLMGR this,LPCITEMIDLIST pidl,LPSTR pOut)
|
||
|
{ TRACE(pidl,"(%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(pidl,"(%p)->(%p,%p,%u)\n",this,pidl,pOut,uSize);
|
||
|
if(PidlMgr_IsMyComputer(this,pidl))
|
||
|
{ pidlTemp = ILGetNext(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(pidl,"(%p)->(pidl=%p)\n",this,pidl);
|
||
|
|
||
|
if(pidl)
|
||
|
{ while(pidl->mkid.cb)
|
||
|
{ pidlLast = (LPITEMIDLIST)pidl;
|
||
|
pidl = ILGetNext(pidl);
|
||
|
}
|
||
|
}
|
||
|
return pidlLast;
|
||
|
}
|
||
|
/**************************************************************************
|
||
|
* PidlMgr_GetItemText()
|
||
|
* Gets the text for only this item
|
||
|
*/
|
||
|
DWORD PidlMgr_GetItemText(LPPIDLMGR this,LPCITEMIDLIST pidl, LPSTR lpszText, UINT16 uSize)
|
||
|
{ TRACE(pidl,"(%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(pidl,"%p->(%p)\n",this,pidl);
|
||
|
|
||
|
if (! pidl)
|
||
|
return FALSE;
|
||
|
|
||
|
return ( pidl->mkid.cb == 0x00 );
|
||
|
}
|
||
|
|
||
|
BOOL32 PidlMgr_IsMyComputer(LPPIDLMGR this,LPCITEMIDLIST pidl)
|
||
|
{ LPPIDLDATA pData;
|
||
|
TRACE(pidl,"%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(pidl,"%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(pidl,"%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(pidl,"%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(pidl,"(%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(pidl,"(%p)->(%p)\n",this,pidl);
|
||
|
|
||
|
if(!pidl)
|
||
|
{ return 0;
|
||
|
}
|
||
|
|
||
|
if(PidlMgr_IsMyComputer(this,pidl))
|
||
|
{ pidlTemp = ILGetNext(pidl);
|
||
|
TRACE(pidl,"-- (%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 = ILGetNext(pidlTemp);
|
||
|
}
|
||
|
|
||
|
//add one for the NULL terminator
|
||
|
TRACE(pidl,"-- (%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 = ILGetNext(pidlTemp);
|
||
|
|
||
|
TRACE(pidl,"-- (%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(pidl,"-- (%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(pidl,"(%p)->(pidl=%p %p 0x%08lx)\n",this,pidl,lpszValue,dwSize);
|
||
|
|
||
|
if(!pidl)
|
||
|
{ return 0;
|
||
|
}
|
||
|
|
||
|
while(pidlTemp->mkid.cb && !PidlMgr_IsValue(this,pidlTemp))
|
||
|
{ pidlTemp = ILGetNext(pidlTemp);
|
||
|
}
|
||
|
|
||
|
if(!pidlTemp->mkid.cb)
|
||
|
{ return 0;
|
||
|
}
|
||
|
|
||
|
PidlMgr_GetItemText(this, pidlTemp, szText, sizeof(szText));
|
||
|
|
||
|
if(!lpszValue)
|
||
|
{ return strlen(szText) + 1;
|
||
|
}
|
||
|
strcpy(lpszValue, szText);
|
||
|
TRACE(pidl,"-- (%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(pidl,"(%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(pidl,"(%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(pidl,"-- (%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(pidl,"(%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(pidl,"-- (%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(pidl,"(%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(pidl,"- (%p)->create My Computer: %s\n",this,debugstr_a(pData->szText));
|
||
|
break;
|
||
|
case PT_DRIVE:
|
||
|
memcpy(pData->szText, pIn, uInSize);
|
||
|
TRACE(pidl,"- (%p)->create Drive: %s\n",this,debugstr_a(pData->szText));
|
||
|
break;
|
||
|
case PT_FOLDER:
|
||
|
case PT_VALUE:
|
||
|
memcpy(pData->szText, pIn, uInSize);
|
||
|
TRACE(pidl,"- (%p)->create Value: %s\n",this,debugstr_a(pData->szText));
|
||
|
break;
|
||
|
default:
|
||
|
FIXME(pidl,"- (%p) wrong argument\n",this);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
pidlTemp = ILGetNext(pidlTemp);
|
||
|
pidlTemp->mkid.cb = 0x00;
|
||
|
}
|
||
|
TRACE(pidl,"-- (%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(pidl,"(%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(pidl,"-- (%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(pidl,"(%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(pidl,"(%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;
|
||
|
}
|