Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

553 lines
12 KiB

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