|
|
/**************************************************************************
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
Copyright 1998 Microsoft Corporation. All Rights Reserved. **************************************************************************/
/**************************************************************************
File: PidlMgr.cpp Description: Implements CPidlMgr.
**************************************************************************/
/**************************************************************************
#include statements
**************************************************************************/
#include "PidlMgr.h"
#include "ShlFldr.h"
#include "Guid.h"
#include "resource.h"
/**************************************************************************
CPidlMgr::CPidlMgr
**************************************************************************/
CPidlMgr::CPidlMgr() { g_DllRefCount++;
//get the shell's IMalloc pointer
//we'll keep this until we get destroyed
if(FAILED(SHGetMalloc(&m_pMalloc))) { delete this; } }
/**************************************************************************
CPidlMgr::~CPidlMgr
**************************************************************************/
CPidlMgr::~CPidlMgr() { if(m_pMalloc) m_pMalloc->Release();
g_DllRefCount--; }
/**************************************************************************
CPidlMgr::Create()
Creates a new PIDL **************************************************************************/
LPITEMIDLIST CPidlMgr::Create(VOID) { LPITEMIDLIST pidlOut; USHORT uSize;
pidlOut = NULL;
/*
Calculate the size. This consists of the ITEMIDLIST plus the size of our private PIDL structure. */ uSize = sizeof(ITEMIDLIST) + sizeof(PIDLDATA);
/*
Allocate the memory, adding an additional ITEMIDLIST for the NULL terminating ID List. */ pidlOut = (LPITEMIDLIST)m_pMalloc->Alloc(uSize + sizeof(ITEMIDLIST));
if(pidlOut) { LPITEMIDLIST pidlTemp = pidlOut;
//set the size of this item
pidlTemp->mkid.cb = uSize;
//set the NULL terminator to 0
pidlTemp = GetNextItem(pidlTemp); pidlTemp->mkid.cb = 0; pidlTemp->mkid.abID[0] = 0; }
return pidlOut; }
/**************************************************************************
CPidlMgr::Delete()
Deletes a PIDL **************************************************************************/
VOID CPidlMgr::Delete(LPITEMIDLIST pidl) { m_pMalloc->Free(pidl); }
/**************************************************************************
CPidlMgr::GetNextItem() **************************************************************************/
LPITEMIDLIST CPidlMgr::GetNextItem(LPCITEMIDLIST pidl) { if(pidl) { return (LPITEMIDLIST)(LPBYTE)(((LPBYTE)pidl) + pidl->mkid.cb); } else return NULL; }
/**************************************************************************
CPidlMgr::GetSize() **************************************************************************/
UINT CPidlMgr::GetSize(LPCITEMIDLIST pidl) { UINT cbTotal = 0; LPITEMIDLIST pidlTemp = (LPITEMIDLIST)pidl;
if(pidlTemp) { while(pidlTemp->mkid.cb) { cbTotal += pidlTemp->mkid.cb; pidlTemp = GetNextItem(pidlTemp); }
//add the size of the NULL terminating ITEMIDLIST
cbTotal += sizeof(ITEMIDLIST); }
return cbTotal; }
/**************************************************************************
CPidlMgr::GetLastItem()
Gets the last item in the list **************************************************************************/
LPITEMIDLIST CPidlMgr::GetLastItem(LPCITEMIDLIST pidl) { LPITEMIDLIST pidlLast = NULL;
//get the PIDL of the last item in the list
while(pidl && pidl->mkid.cb) { pidlLast = (LPITEMIDLIST)pidl; pidl = GetNextItem(pidl); }
return pidlLast; }
/**************************************************************************
CPidlMgr::Copy() **************************************************************************/
LPITEMIDLIST CPidlMgr::Copy(LPCITEMIDLIST pidlSource) { LPITEMIDLIST pidlTarget = NULL; UINT cbSource = 0;
if(NULL == pidlSource) return NULL;
// Allocate the new pidl
cbSource = GetSize(pidlSource); pidlTarget = (LPITEMIDLIST)m_pMalloc->Alloc(cbSource); if(!pidlTarget) return NULL;
// Copy the source to the target
CopyMemory(pidlTarget, pidlSource, cbSource);
return pidlTarget; }
/**************************************************************************
CPidlMgr::CopySingleItem()
**************************************************************************/
LPITEMIDLIST CPidlMgr::CopySingleItem(LPCITEMIDLIST pidlSource) { LPITEMIDLIST pidlTarget = NULL; UINT cbSource = 0;
if(NULL == pidlSource) return NULL;
// Allocate the new pidl
cbSource = pidlSource->mkid.cb; pidlTarget = (LPITEMIDLIST)m_pMalloc->Alloc(cbSource + sizeof(ITEMIDLIST)); if(!pidlTarget) return NULL;
// Copy the source to the target
ZeroMemory(pidlTarget, cbSource + sizeof(ITEMIDLIST)); CopyMemory(pidlTarget, pidlSource, cbSource);
return pidlTarget; }
/**************************************************************************
CPidlMgr::GetDataPointer() **************************************************************************/
inline LPPIDLDATA CPidlMgr::GetDataPointer(LPCITEMIDLIST pidl) { if(!pidl) return NULL;
return (LPPIDLDATA)(pidl->mkid.abID); }
/**************************************************************************
CPidlMgr::Concatenate()
Create a new PIDL by combining two existing PIDLs. **************************************************************************/
LPITEMIDLIST CPidlMgr::Concatenate(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) { LPITEMIDLIST pidlNew; UINT cb1 = 0, cb2 = 0;
//are both of these NULL?
if(!pidl1 && !pidl2) return NULL;
//if pidl1 is NULL, just return a copy of pidl2
if(!pidl1) { pidlNew = Copy(pidl2);
return pidlNew; }
//if pidl2 is NULL, just return a copy of pidl1
if(!pidl2) { pidlNew = Copy(pidl1);
return pidlNew; }
cb1 = GetSize(pidl1) - sizeof(ITEMIDLIST);
cb2 = GetSize(pidl2);
//create the new PIDL
pidlNew = (LPITEMIDLIST)m_pMalloc->Alloc(cb1 + cb2);
if(pidlNew) { //copy the first PIDL
CopyMemory(pidlNew, pidl1, cb1); //copy the second PIDL
CopyMemory(((LPBYTE)pidlNew) + cb1, pidl2, cb2); }
return pidlNew; }
/**************************************************************************
CPidlMgr::CreateFolderPidl()
Create a new folder PIDL. **************************************************************************/
LPITEMIDLIST CPidlMgr::CreateFolderPidl(LPCTSTR pszName) { LPITEMIDLIST pidl = Create(); LPPIDLDATA pData = GetDataPointer(pidl);
if(pData) { pData->fFolder = TRUE;
lstrcpyn(pData->szName, pszName, MAX_NAME);
pData->szData[0] = 0; }
return pidl; }
/**************************************************************************
CPidlMgr::CreateItemPidl()
Create a new item PIDL. **************************************************************************/
LPITEMIDLIST CPidlMgr::CreateItemPidl( LPCTSTR pszName, LPCTSTR pszData) { LPITEMIDLIST pidl = Create(); LPPIDLDATA pData = GetDataPointer(pidl);
if(pData) { pData->fFolder = FALSE; lstrcpyn(pData->szName, pszName, MAX_NAME); lstrcpyn(pData->szData, pszData, MAX_DATA); }
return pidl; }
/**************************************************************************
CPidlMgr::SetDataPidl()
Set a data in the PIDL. **************************************************************************/
LPITEMIDLIST CPidlMgr::SetDataPidl(LPITEMIDLIST pidl, LPPIDLDATA pSourceData, PIDLDATATYPE pidldatatype) { if (!pidl) pidl = Create();
LPPIDLDATA pData = GetDataPointer(pidl);
if(pData) { if (pidldatatype & FOLDER) pData->fFolder = pSourceData->fFolder; if (pidldatatype & NAME) lstrcpyn(pData->szName, pSourceData->szName, MAX_NAME); if (pidldatatype & DATA) lstrcpyn(pData->szData, pSourceData->szData, MAX_DATA); if (pidldatatype & ICON) pData->iIcon = pSourceData->iIcon; if (pidldatatype & URL) lstrcpyn(pData->szUrl, pSourceData->szUrl, MAX_DATA); }
return pidl; }
/**************************************************************************
CPidlMgr::GetName()
Gets the name for this item **************************************************************************/
int CPidlMgr::GetName(LPCITEMIDLIST pidl, LPTSTR pszText, DWORD dwSize) { if(!IsBadWritePtr(pszText, dwSize)) { *pszText = 0;
LPPIDLDATA pData = GetDataPointer(pidl);
if(pData) { lstrcpyn(pszText, pData->szName, dwSize); return lstrlen(pszText); } }
return 0; }
/**************************************************************************
CPidlMgr::GetRelativeName()
Gets the full name for this item **************************************************************************/
int CPidlMgr::GetRelativeName(LPCITEMIDLIST pidl, LPTSTR pszText, DWORD dwSize) { if(!IsBadWritePtr(pszText, dwSize)) { LPITEMIDLIST pidlTemp; *pszText = 0;
//walk the list, getting the name for each item
pidlTemp = (LPITEMIDLIST)pidl; while(pidlTemp && pidlTemp->mkid.cb) { LPTSTR pszCurrent = pszText + lstrlen(pszText); dwSize -= GetName(pidlTemp, pszCurrent, dwSize); pidlTemp = GetNextItem(pidlTemp);
//don't add a backslash to the last item
if(pidlTemp && pidlTemp->mkid.cb) { SmartAppendBackslash(pszCurrent); } } return lstrlen(pszText); }
return 0; }
/**************************************************************************
CPidlMgr::GetData()
Gets the data for this item **************************************************************************/
int CPidlMgr::GetData(LPCITEMIDLIST pidl, LPTSTR pszText, DWORD dwSize) { if(!IsBadWritePtr(pszText, dwSize)) { *pszText = 0;
LPPIDLDATA pData = GetDataPointer(pidl);
if(pData) { lstrcpyn(pszText, pData->szData, dwSize); return lstrlen(pszText); } }
return 0; }
/**************************************************************************
CPidlMgr::IsFolder()
Determines if the item is a folder **************************************************************************/
BOOL CPidlMgr::IsFolder(LPCITEMIDLIST pidl) { LPPIDLDATA pData = GetDataPointer(pidl);
if(pData) { return pData->fFolder; }
return FALSE; }
/**************************************************************************
CPidlMgr::SetData()
**************************************************************************/
int CPidlMgr::SetData(LPCITEMIDLIST pidl, LPCTSTR pszData) { LPPIDLDATA pData = GetDataPointer(pidl);
if(pData) { lstrcpyn(pData->szData, pszData, MAX_DATA);
return lstrlen(pData->szData); }
return 0; }
/**************************************************************************
CPidlMgr::GetIcon()
Determines if the item is a folder **************************************************************************/
int CPidlMgr::GetIcon(LPCITEMIDLIST pidl) { LPPIDLDATA pData = GetDataPointer(pidl);
if(pData) { return pData->iIcon; }
return FALSE; }
/**************************************************************************
CPidlMgr::GetUrl()
Gets the data for this item **************************************************************************/
int CPidlMgr::GetUrl(LPCITEMIDLIST pidl, LPTSTR pszText, DWORD dwSize) { if(!IsBadWritePtr(pszText, dwSize)) { *pszText = 0;
LPPIDLDATA pData = GetDataPointer(pidl);
if(pData) { lstrcpyn(pszText, pData->szUrl, dwSize); return lstrlen(pszText); } }
return 0; }
|