Sweden-Number/dlls/shell32/pidl.c

847 lines
22 KiB
C
Raw Normal View History

Release 980822 Sat Aug 22 17:46:19 1998 Ulrich Weigand <weigand@informatik.uni-erlangen.de> * [include/dosexe.h] [include/module.h] [include/pe_image.h] [include/process.h] [include/windows.h] [loader/dos/module.c] [loader/module.c] [loader/ne/module.c] [loader/pe_image.c] [scheduler/process.c] [win32/process.c] Partially implemented CreateProcess32. * [win32/device.c] [relay32/kernel32.spec] [scheduler/k32obj.c] [misc/registry.c] [win32/file.c] Partially implemented VxDCall (VMM registry services). * [files/dos_fs.c] DOSFS_FindNext made thread-safe. * [include/sig_context.h] [include/syslevel.h] [loader/signal.c] [scheduler/syslevel.c] [tools/build.c] Replaced CALLTO16_Current_fs by SYSLEVEL_Win16CurrentTeb. * [win32/kernel32.c] Bugfix: QT_Thunk/FT_Thunk should return 'long' in DX:AX, not EAX. * [if1632/relay.c] [relay32/builtin32.c] [windows/msgbox.c] [msdos/int20.c] [msdos/int21.c] Use ExitProcess instead of TASK_KillCurrentTask. * [include/task.h] [include/thread.h] [loader/task.c] [scheduler/thread.c] [include/queue.h] [windows/message.c] [windows/queue.c] [windows/win.c] Prevent Win32 threads from entering the TASK_Reschedule loop. (Note: Win32 messaging still doesn't work correctly; this patch is just preventing the system from crashing when Win32 threads call messaging functions. Messages will probably still get lost.) * [scheduler/critsection.c] Deactivated the use of SEM_UNDO for the SYSTEM_LOCK semaphore; for some reason, this leads to problems after threads terminate... Sat Aug 22 15:00:00 1998 Jürgen Schmied <juergen.schmied@metronet.de> * [include/authors.h] New file, includes all names of the developer (former shell.c) * [Makefile.in][configure][configure.in][dlls/Makefile.in] [dlls/shell32/Makefile.in][shres.rc] Created dlls/shell32 and moved the shell32 stuff in it. Started to create internal resources. * [dlls/shell32/*] Split the shell32 implementation into smaller files. New classes: IContextMenu, IExtractIcon, IShellView. Implemented Shell_GetImageList(). shell32 links to comctl32 now dynamically so it can use internal/external implementations. * [documentation/internal-dll] [documentation/shell32] New, could anybody do a spellcheck? * [include/commctrl.h] Many new LV constants, structures, functions. * [controls/comctl32undoc.c] Rewrote the DSA* functions. * [windows/winpos.c] SetShellWindow32, GetShellWindow32. Sat Aug 22 14:02:15 1998 Alexander Lukyanov <lav@long.yar.ru> * [loader/resource.c] Mark last accelerator as such in LoadAccelerators32W. * [relay32/shell32.spec] [misc/shell.c] Add stubs for SHGetSpecialFolderPath[AW]. Sat Aug 22 02:07:42 1998 Adrian Harvey <adrian@select.com.au> * [include/file.h] [file/file.c] [msdos/int21.c] [msdos/vxd.c] [misc/lzexpand.c] [win32/kernel32.c] [documentation/filehandles] Fixed file handle handling. Created universal HFILE16 to HFILE32 translation macro from msdos/int21 code by Ove Kaaven. Used macro in all Win16 functions so that win32 handles are translated to avoid DOS/Win16 stdxx handles. Removed handle translation from int21.c where Win16 functions are called. Changed remaining calls to use new macro names. Documented filehandle handling and differences between win 16 & 32. Fri Aug 21 20:32:49 1998 Alexandre Julliard <julliard@lrc.epfl.ch> * [server/process.c] [server/thread.c] Implemented object wait queues and synchronization. Fri Aug 21 18:40:02 1998 Huw D M Davies <daviesh@abacus.physics.ox.ac.uk> * [graphics/psdrv/*] DEVMODE dmPaper{Width|Length} fields are in 0.1mm. Select a 100 pixel default font in CreateDC. Thu Aug 20 22:47:39 1998 Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de> * [objects/bitmap.c] Handle bits=32 in SetBitmapBits32 and GetBitmapBits32. * [msdos/int21.c] Add handling of Int21 0A and 37. * [misc/commdlg.c] Use MapHModuleLS and MapHModuleSL when translating HINSTANCE16 to HINSTANCE32 and vice versa. * [win32/file.c] CreateFile32A: Abort if filename == NULL. Thu Aug 20 12:28:31 1998 Marcus Meissner <marcus@jet.franken.de> * [*/*] Lots of missing prototypes added, some parameter types adapted to match SDK. * [debugger/stabs.c] Don't loop forever if we don't find wine or one of the libxxx.so. * [loader/ne/module.c] Implemented MapHModuleLS,MapHModuleSL,MapHinstLS,MapHinstSL. * [misc/network.c] Implemented WNetGetUser32A. * [misc/shellord.c] Implemented ILRemoveLastID. * [multimedia/dsound.c] Fixed StarCraft memory leak. * [graphics/ddraw.c] Removed some unnecessary simple relaying functions, tried polishing up the Xlib implementation (still doesn't work), temp. removed Xshm code (to be remerged with working Xlib code). Tue Aug 18 22:29:17 1998 Ove Kaaven <ovek@arcticnet.no> * [multimedia/mmio.c] [multimedia/mmsystem.c] Fixed most mmio bugs, fully implementing mmioSetBuffer buffering, ability to read memory files, and the sndPlaySound() SND_MEMORY flag. Most mmio-using programs now work fine. * [include/dosexe.h] [include/miscemu.h] [include/module.h] [loader/module.c] [loader/task.c] [msdos/dosmem.c] Improved DOS VM flexibility and portability somewhat. (Did I get the #ifdefs right this time, BSD-ers?) * [msdos/int21.c] Made "Get Current PSP address" work as expected in a DOS VM. * [loader/dos/*] Began improving flexibility and portability somewhat. It should be easier to add DPMI RMCB callbacks now. The DOS VM no longer leaves big files lying around in /tmp after a crash. Tue Aug 18 12:38:31 1998 Turchanov Sergey <turchanov@usa.net> * [relay32/winmm.spec] This patch allows WinAmp to play WAV files (at least in PCM format). Sun Aug 16 05:34:13 1998 Pablo Saratxaga <srtxg@chanae.alphanet.ch> * [windows/keyboard.c] Corrected keyboard code to properly handle keys : ? ~ and " on non US keyboards. Sat Aug 15 18:47:14 1998 Brian Craft <bcboy@dorothy.wanglab.brandeis.edu> * [windows/win.c] Fixed severe bug in EnumChildWindwos(). Thu Aug 13 21:05:35 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de> * [controls/tooltips.c] Fixed some bugs. Added subclassing support. * [controls/toolbar.c] Improved tooltip integration. Fixed some bugs. * [controls/commctrl.c] Changed control registration and added some documentation. Fixed ShowHideMenuCtl. * [controls/rebar.c][include/rebar.h][include/commctrl.h] Improved rebar implementation (still no display). * [controls/pager.c][include/pager.h][include/commctrl.h] Improved pager implementation (still no display). * [misc/imagelist.c] Fixed a bug. * [documentation/common_controls] Updated. Sun Aug 9 19:50:20 1998 James Juran <jrj120@psu.edu> * [Makefile.in] [documentation/Makefile.in] [programs/Makefile.in] [programs/*/Makefile.in] Added uninstall rules, cleaned up install rules a little bit. Sun Aug 9 13:21:35 1998 Andreas Mohr <100.30936@germany.net> * [loader/ne/module.c] [if1632/kernel.spec] Added the undocumented HIWORD of GetModuleHandle (hFirstModule). * [loader/ne/segment.c] Wine forgot to set some NE_SEGFLAGS_*. Combined with another loader change, this fixed the "BLINKER -- error in loading module" or ghost MessageBox problem that about 1% of all Windows programs have. Some BLINKER programs still don't work, though. But I'm working on it, with great help from Blinkinc. * [loader/task.c] InitTask needs to decrement the SP register by two as Win95 does. Sun Aug 9 02:41:28 1998 Ulrich Weigand <weigand@informatik.uni-erlangen.de> * [if1632/kernel.spec] [relay32/kernel32.spec] [scheduler/syslevel.c] [loader/main.c] [win32/ordinals.c] [include/syslevel.h] [scheduler/Makefile.in] Implemented Win95 'syslevel' routines (including Win16Lock). * [if1632/relay.c] [if1632/thunk.c] [tools/build.c] [loader/task.c] [loader/ne/segment.c] [win32/kernel32.c] [memory/selector.c] [include/stackframe.h] [include/thread.h] 16-bit %fs handling revised. Use Win16Lock where appropriate. * [include/thread.h] [scheduler/synchro.c] [windows/message.c] [windows/queue.c] [win32/process.c] Implemented MsgWaitForMultipleObjects. * [files/change.c] [files/Makefile.in] [scheduler/k32obj.c] [win32/newfns.c] Implemented (dummy) file change notification objects. * [debugger/dbg.y] [scheduler/process.c] [scheduler/thread.c] [include/process.h] [include/thread.h] Suspend all threads except current when hitting debugger break point. * [objects/dib.c] Bugfix for CreateDIBSection.
1998-08-22 21:03:56 +02:00
/*
* 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;
}