📄 pidlmgr.cpp
字号:
/**************************************************************************
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 1997 Microsoft Corporation. All Rights Reserved.
**************************************************************************/
/**************************************************************************
File: PidlMgr.cpp
Description: Implements CPidlMgr.
**************************************************************************/
/**************************************************************************
#include statements
**************************************************************************/
#include "stdafx.h"
#include "PidlMgr.h"
#include "resource.h"
/**************************************************************************
CPidlMgr::CPidlMgr
**************************************************************************/
DWORD GetRootKeyText(HKEY hKeyRoot, LPTSTR lpszOut, DWORD dwOutSize)
{
lstrcpyn(lpszOut, TEXT("服务器根目录"), dwOutSize);
return 10 + 1 ;
}
BOOL AddBackslash(LPTSTR lpszString)
{
if(*lpszString && *(lpszString + lstrlen(lpszString) - 1) != '\\')
{
lstrcat(lpszString, TEXT("\\"));
return TRUE;
}
return FALSE;
}
CPidlMgr::CPidlMgr()
{
//get the shell's IMalloc pointer
//we'll keep this until we get destroyed
if(FAILED(SHGetMalloc(&m_pMalloc)))
{
delete this;
}
g_DllRefCount++;
}
/**************************************************************************
CPidlMgr::~CPidlMgr
**************************************************************************/
CPidlMgr::~CPidlMgr()
{
if(m_pMalloc)
m_pMalloc->Release();
g_DllRefCount--;
}
/**************************************************************************
CPidlMgr::Create(DWORD, LPVOID, DWORD)
Creates a new PIDL
**************************************************************************/
LPITEMIDLIST CPidlMgr::Create(PIDLTYPE type, LPVOID pIn, USHORT uInSize)
{
LPITEMIDLIST pidlOut;
USHORT uSize;
pidlOut = NULL;
/*
Calculate the size. This consists of the ITEMIDLIST, the PIDL structure plus
the size of the data. We subtract the size of an HKEY because that is included
in uInSize.
*/
uSize = sizeof(ITEMIDLIST) + (sizeof(PIDLDATA) - sizeof(HKEY)) + uInSize;
/*
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;
LPPIDLDATA pData;
//set the size of this item
pidlTemp->mkid.cb = uSize;
//set the data for this item
pData = GetDataPointer(pidlTemp);
pData->type = type;
switch(type)
{
case PT_ROOTKEY:
pData->hRootKey = *(HKEY*)pIn;
break;
case PT_SUBKEY:
case PT_VALUE:
CopyMemory(pData->szText, pIn, uInSize);
break;
}
//set the NULL terminator to 0
pidlTemp = GetNextItem(pidlTemp);
pidlTemp->mkid.cb = 0;
pidlTemp->mkid.abID[0] = 0;
}
return pidlOut;
}
/**************************************************************************
CPidlMgr::Delete(HKEY)
Deletes a PIDL
**************************************************************************/
void CPidlMgr::Delete(LPITEMIDLIST pidl)
{
m_pMalloc->Free(pidl);
}
/**************************************************************************
CPidlMgr::CreateRootKey()
Creates a root key PIDL
**************************************************************************/
LPITEMIDLIST CPidlMgr::CreateRootKey(HKEY hKeyRoot)
{
return Create(PT_ROOTKEY, (LPVOID)&hKeyRoot, sizeof(hKeyRoot));
}
/**************************************************************************
CPidlMgr::CreateSubKey()
Creates a sub key PIDL
**************************************************************************/
LPITEMIDLIST CPidlMgr::CreateSubKey(LPCTSTR lpszNew)
{
return Create(PT_SUBKEY, (LPVOID)lpszNew, (lstrlen(lpszNew) + 1) * sizeof(TCHAR));
}
/**************************************************************************
CPidlMgr::CreateValue()
Creates a value PIDL
**************************************************************************/
LPITEMIDLIST CPidlMgr::CreateValue(LPCTSTR lpszNew)
{
return Create(PT_VALUE, (LPVOID)lpszNew, (lstrlen(lpszNew) + 1) * sizeof(TCHAR));
}
/**************************************************************************
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::GetData(PIDLTYPE, LPCITEMIDLIST, LPVOID, USHORT)
**************************************************************************/
DWORD CPidlMgr::GetData(PIDLTYPE type, LPCITEMIDLIST pidl, LPVOID pOut, USHORT uOutSize)
{
if(!pidl)
return 0;
LPPIDLDATA pData = GetDataPointer(pidl);
DWORD dwReturn = 0;
//copy the data
switch(type)
{
case PT_ROOTKEY:
if(uOutSize < sizeof(HKEY))
return 0;
if(PT_ROOTKEY != pData->type)
return 0;
*(HKEY*)pOut = pData->hRootKey;
dwReturn = sizeof(pData->hRootKey);
break;
case PT_SUBKEY:
case PT_VALUE:
case PT_TEXT:
*(LPTSTR)pOut = 0;
lstrcpyn((LPTSTR)pOut, pData->szText, uOutSize);
dwReturn = lstrlen((LPTSTR)pOut);
break;
}
return dwReturn;
}
/**************************************************************************
CPidlMgr::GetRootKey()
**************************************************************************/
BOOL CPidlMgr::GetRootKey(LPCITEMIDLIST pidl, HKEY *phKeyRoot)
{
return (BOOL)GetData(PT_ROOTKEY, pidl, (LPVOID)phKeyRoot, sizeof(HKEY));
}
/**************************************************************************
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
if(pidl)
{
while(pidl->mkid.cb)
{
pidlLast = (LPITEMIDLIST)pidl;
pidl = GetNextItem(pidl);
}
}
return pidlLast;
}
/**************************************************************************
CPidlMgr::GetItemText()
Gets the text for only this item
**************************************************************************/
DWORD CPidlMgr::GetItemText(LPCITEMIDLIST pidl, LPTSTR lpszText, USHORT uSize)
{
//if this is a root key, it needs to be handled specially
if(IsRootKey(pidl))
{
HKEY hKey;
if(!GetRootKey(pidl, &hKey))
return 0;
return GetRootKeyText(hKey, lpszText, uSize);
}
return GetData(PT_TEXT, pidl, (LPVOID)lpszText, uSize);
}
/**************************************************************************
CPidlMgr::GetSubKeyText()
Creates a sub key string from a PIDL, filtering out the root key and
value, if either is present.
**************************************************************************/
DWORD CPidlMgr::GetSubKeyText(LPCITEMIDLIST pidl, LPTSTR lpszSubKey, DWORD dwSize)
{
if(!pidl)
return 0;
LPITEMIDLIST pidlTemp;
DWORD dwCopied = 0;
/*
This may be a list of items, so if the first item is a key rather than a
string, skip the first item because it contains the root key.
*/
if(IsRootKey(pidl))
pidlTemp = GetNextItem(pidl);
else
pidlTemp = (LPITEMIDLIST)pidl;
//if this is NULL, return the required size of the buffer
if(!lpszSubKey)
{
while(pidlTemp->mkid.cb)
{
LPPIDLDATA pData = GetDataPointer(pidlTemp);
//add the length of this item plus one for the backslash
dwCopied += lstrlen(pData->szText) + 1;
pidlTemp = GetNextItem(pidlTemp);
}
//add one for the NULL terminator
return dwCopied + 1;
}
*lpszSubKey = 0;
while(pidlTemp->mkid.cb && (dwCopied < dwSize))
{
LPPIDLDATA pData = GetDataPointer(pidlTemp);
//if this item is a value, then skip it and finish
if(PT_VALUE == pData->type)
break;
lstrcat(lpszSubKey, pData->szText);
lstrcat(lpszSubKey, TEXT("\\"));
dwCopied += lstrlen(pData->szText) + 1;
pidlTemp = GetNextItem(pidlTemp);
}
//remove the last backslash if necessary
if(dwCopied)
{
if(*(lpszSubKey + lstrlen(lpszSubKey) - 1) == '\\')
{
*(lpszSubKey + lstrlen(lpszSubKey) - 1) = 0;
dwCopied--;
}
}
return dwCopied;
}
/**************************************************************************
CPidlMgr::GetValueText()
Gets the text for the last item in the list
**************************************************************************/
DWORD CPidlMgr::GetValueText(LPCITEMIDLIST pidl, LPTSTR lpszValue, DWORD dwSize)
{
if(!pidl)
return 0;
LPCITEMIDLIST pidlTemp = pidl;
TCHAR szText[MAX_PATH];
/*
This may be a list of items, so search through the list looking for an item
that is a value. There should be only one, and it should be the last one, but
we will assume it can be anywhere and only copy the first one.
*/
while(pidlTemp->mkid.cb && !IsValue(pidlTemp))
{
pidlTemp = GetNextItem(pidlTemp);
}
//we didn't find a value pidl
if(!pidlTemp->mkid.cb)
return 0;
//get the item's text
GetItemText(pidlTemp, szText, sizeof(szText));
//if this is NULL, return the required size of the buffer
if(!lpszValue)
{
return lstrlen(szText) + 1;
}
lstrcpy(lpszValue, szText);
return lstrlen(lpszValue);
}
/**************************************************************************
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::IsRootKey()
**************************************************************************/
BOOL CPidlMgr::IsRootKey(LPCITEMIDLIST pidl)
{
LPPIDLDATA pData = GetDataPointer(pidl);
return (PT_ROOTKEY == pData->type);
}
/**************************************************************************
CPidlMgr::IsSubKey()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -