windows-nt/Source/XPSP1/NT/shell/ext/occache/enum.cpp

433 lines
11 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
#include "enum.h"
BOOL GetVersion(LPCONTROLPIDL pcpidl, LPTSTR lpszBuf);
BOOL GetTimeInfo(
BOOL bCreation, LPCONTROLPIDL pcpidl,
FILETIME* lpTime, LPTSTR lpszBuf, BOOL bShowTime);
// Also defined in nt\private\inet\urlmon\isctrl.cxx
const TCHAR *g_pszLastCheckDateKey = "LastCheckDate";
const TCHAR *g_pszUpdateInfo = "UpdateInfo";
#if defined(ALIGNMENT_MACHINE)
BOOL
__inline
static
uaGetControlInfo(
IN HANDLE hControlHandle,
IN UINT nFlag,
IN OUT DWORD UNALIGNED *lpdwuData,
IN OUT LPTSTR lpszBuf,
IN int nBufLen
)
{
DWORD dwData;
LPDWORD lpdwData;
BOOL result;
if (lpdwuData != NULL) {
dwData = *lpdwuData;
lpdwData = &dwData;
} else {
lpdwData = NULL;
}
result = GetControlInfo( hControlHandle,
nFlag,
lpdwData,
lpszBuf,
nBufLen );
if (lpdwuData != NULL) {
*lpdwuData = dwData;
}
return result;
}
BOOL
__inline
static
uaGetTimeInfo(
IN BOOL bCreation,
IN OUT LPCONTROLPIDL pcpidl,
IN OUT FILETIME UNALIGNED *lpuTime,
IN OUT LPTSTR lpszBuf,
IN BOOL bShowTime
)
{
FILETIME time;
LPFILETIME lpTime;
BOOL result;
if (lpuTime != NULL) {
time = *lpuTime;
lpTime = &time;
} else {
lpTime = NULL;
}
result = GetTimeInfo( bCreation,
pcpidl,
lpTime,
lpszBuf,
bShowTime );
if (lpuTime != NULL) {
*lpuTime = time;
}
return result;
}
#else
#define uaGetControlInfo GetControlInfo
#define uaGetTimeInfo GetTimeInfo
#endif
///////////////////////////////////////////////////////////////////////////////
// IEnumIDList methods
CControlFolderEnum::CControlFolderEnum(STRRET &str, LPCITEMIDLIST pidl, UINT shcontf) :
m_shcontf(shcontf)
{
DebugMsg(DM_TRACE, TEXT("cfe - CControlFolderEnum() called"));
m_cRef = 1;
DllAddRef();
m_bEnumStarted = FALSE;
m_hEnumControl = NULL;
StrRetToBuf(&str, pidl, m_szCachePath, MAX_PATH);
SHGetMalloc(&m_pMalloc); // won't fail
}
CControlFolderEnum::~CControlFolderEnum()
{
Assert(m_cRef == 0); // we should always have a zero ref count here
DebugMsg(DM_TRACE, TEXT("cfe - ~CControlFolderEnum() called."));
DllRelease();
}
HRESULT CControlFolderEnum_CreateInstance(
LPITEMIDLIST pidl,
UINT shcontf,
LPENUMIDLIST *ppeidl)
{
DebugMsg(DM_TRACE,("cfe - CreateInstance() called."));
if (pidl == NULL)
return HRESULT_FROM_WIN32(ERROR_BAD_ARGUMENTS);
HRESULT hr;
LPSHELLFOLDER pshf = NULL;
if (FAILED(hr = SHGetDesktopFolder(&pshf)))
return hr;
STRRET name;
hr = pshf->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &name);
if (FAILED(hr))
return hr;
*ppeidl = NULL; // null the out param
CControlFolderEnum *pCFE = new CControlFolderEnum(name, pidl, shcontf);
if (!pCFE)
return E_OUTOFMEMORY;
*ppeidl = pCFE;
return S_OK;
}
BOOL GetVersion(LPCONTROLPIDL pcpidl, LPTSTR lpszBuf)
{
Assert(pcpidl != NULL);
LPCTSTR pszLocation = GetStringInfo(pcpidl, SI_LOCATION);
DWORD dwBufLen;
DWORD dwHandle;
BOOL fResult = FALSE;
UINT uLen;
VS_FIXEDFILEINFO *pVersionInfo = NULL;
// Quick copy to handle failure cases
lstrcpy(lpszBuf, g_szUnknownData);
if ((dwBufLen = ::GetFileVersionInfoSize(
(LPTSTR)pszLocation,
&dwHandle)) == 0)
return FALSE;
BYTE *pbData = new BYTE[dwBufLen];
if (pbData == NULL)
return FALSE;
if (GetFileVersionInfo((LPTSTR)pszLocation, dwHandle, dwBufLen, pbData))
{
fResult = VerQueryValue(pbData, "\\", (LPVOID*)&pVersionInfo, &uLen);
if (fResult)
{
wsprintf(lpszBuf, "%d,%d,%d,%d",
(pVersionInfo->dwFileVersionMS & 0xffff0000)>>16,
(pVersionInfo->dwFileVersionMS & 0xffff),
(pVersionInfo->dwFileVersionLS & 0xffff0000)>>16,
(pVersionInfo->dwFileVersionLS & 0xffff));
}
}
delete [] pbData;
return fResult;
}
BOOL GetTimeInfo(
BOOL bCreation,
LPCONTROLPIDL pcpidl,
FILETIME* lpTime,
LPTSTR lpszBuf,
BOOL bShowTime)
{
Assert(pcpidl != NULL);
Assert (lpszBuf != NULL);
if (pcpidl == NULL || lpszBuf == NULL)
return FALSE;
LPCTSTR pszLocation = GetStringInfo(pcpidl, SI_LOCATION);
BOOL fResult = TRUE;
HANDLE hFile = NULL;
WIN32_FIND_DATA findFileData;
TCHAR szTime[TIMESTAMP_MAXSIZE];
TCHAR szDate[TIMESTAMP_MAXSIZE];
SYSTEMTIME sysTime;
FILETIME localTime;
hFile = FindFirstFile(pszLocation, &findFileData);
if (hFile != INVALID_HANDLE_VALUE)
{
// Get the creation time and date information.
if (bCreation)
{
*lpTime = findFileData.ftCreationTime;
FileTimeToLocalFileTime(&findFileData.ftCreationTime, &localTime);
}
else
{
*lpTime = findFileData.ftLastAccessTime;
FileTimeToLocalFileTime(&findFileData.ftLastAccessTime, &localTime);
}
FileTimeToSystemTime(&localTime, &sysTime);
GetDateFormat(
LOCALE_SYSTEM_DEFAULT,
DATE_SHORTDATE,
&sysTime,
NULL,
szDate,
TIMESTAMP_MAXSIZE);
lstrcpy(lpszBuf, szDate);
if (bShowTime)
{
GetTimeFormat(
LOCALE_SYSTEM_DEFAULT,
TIME_NOSECONDS,
&sysTime,
NULL,
szTime,
TIMESTAMP_MAXSIZE
);
lstrcat(lpszBuf, TEXT(" "));
lstrcat(lpszBuf, szTime);
}
FindClose(hFile);
}
else
{
fResult = FALSE;
lstrcpy(lpszBuf, g_szUnknownData);
lpTime->dwLowDateTime = lpTime->dwHighDateTime = 0;
}
return fResult;
}
LPCONTROLPIDL CreateControlPidl(IMalloc *pmalloc, HANDLE hControl)
{
Assert(pmalloc != NULL);
DWORD dw;
GetControlInfo(hControl, GCI_TOTALFILES, &dw, NULL, 0);
ULONG ulSize = sizeof(CONTROLPIDL) + sizeof(USHORT);
ulSize += (dw - 1) * sizeof(DEPENDENTFILEINFO);
LPCONTROLPIDL pcpidl = (LPCONTROLPIDL)pmalloc->Alloc(ulSize);
if (pcpidl)
{
memset(pcpidl, 0, ulSize);
pcpidl->cb = (USHORT)(ulSize - sizeof(USHORT));
pcpidl->ci.cTotalFiles = (UINT)dw;
uaGetControlInfo(hControl, GCI_TOTALSIZE, &(pcpidl->ci.dwTotalFileSize), NULL, 0);
uaGetControlInfo(hControl, GCI_SIZESAVED, &(pcpidl->ci.dwTotalSizeSaved), NULL, 0);
GetControlInfo(hControl, GCI_NAME, NULL, pcpidl->ci.szName, CONTROLNAME_MAXSIZE);
GetControlInfo(hControl, GCI_FILE, NULL, pcpidl->ci.szFile, MAX_PATH);
GetControlInfo(hControl, GCI_CLSID, NULL, pcpidl->ci.szCLSID, MAX_CLSID_LEN);
GetControlInfo(hControl, GCI_TYPELIBID, NULL, pcpidl->ci.szTypeLibID, MAX_CLSID_LEN);
uaGetTimeInfo(TRUE, pcpidl, &(pcpidl->ci.timeCreation), pcpidl->ci.szCreation, TRUE);
uaGetTimeInfo(FALSE, pcpidl, &(pcpidl->ci.timeLastAccessed), pcpidl->ci.szLastAccess, FALSE);
GetControlInfo(hControl, GCI_CODEBASE, NULL, pcpidl->ci.szCodeBase, INTERNET_MAX_URL_LENGTH);
uaGetControlInfo(hControl, GCI_ISDISTUNIT, &(pcpidl->ci.dwIsDistUnit), NULL, 0);
uaGetControlInfo(hControl, GCI_STATUS, &(pcpidl->ci.dwStatus), NULL, 0);
uaGetControlInfo(hControl, GCI_HAS_ACTIVEX, &(pcpidl->ci.dwHasActiveX), NULL, 0);
uaGetControlInfo(hControl, GCI_HAS_JAVA, &(pcpidl->ci.dwHasJava), NULL, 0);
if (pcpidl->ci.dwIsDistUnit)
{
GetControlInfo(hControl, GCI_DIST_UNIT_VERSION, NULL, pcpidl->ci.szVersion, VERSION_MAXSIZE);
}
else
{
GetVersion(pcpidl, pcpidl->ci.szVersion);
}
LONG lResult = ERROR_SUCCESS;
DEPENDENTFILEINFO UNALIGNED *pInfo = &(pcpidl->ci.dependentFile);
dw = GetTotalNumOfFiles(pcpidl);
for (UINT iFile = 0; iFile < (UINT)dw; iFile++)
{
DWORD alignedSize = pInfo->dwSize;
lResult = GetControlDependentFile(
iFile,
hControl,
pInfo->szFile,
&alignedSize,
TRUE);
pInfo->dwSize = alignedSize;
if (lResult != ERROR_SUCCESS)
break;
pInfo = (LPDEPENDENTFILEINFO)(pInfo + 1);
}
}
return pcpidl;
}
//////////////////////////////////
//
// IUnknown Methods...
//
HRESULT CControlFolderEnum::QueryInterface(REFIID iid,void **ppv)
{
DebugMsg(DM_TRACE, TEXT("cfe - QueryInterface called."));
if ((iid == IID_IEnumIDList) || (iid == IID_IUnknown))
{
*ppv = (void *)this;
AddRef();
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}
ULONG CControlFolderEnum::AddRef(void)
{
return ++m_cRef;
}
ULONG CControlFolderEnum::Release(void)
{
if (--m_cRef)
return m_cRef;
delete this;
return 0;
}
HRESULT CControlFolderEnum::Next(
ULONG celt,
LPITEMIDLIST *rgelt,
ULONG *pceltFetched)
{
DebugMsg(DM_TRACE, TEXT("cfe - Next() called."));
// If asking for stuff we don't have, say we don't have any
if (!(m_shcontf & SHCONTF_NONFOLDERS))
return S_FALSE;
LONG lres = ERROR_SUCCESS;
HANDLE hControl = NULL;
LPCONTROLPIDL pcpidl = NULL;
lres = (!m_bEnumStarted ?
FindFirstControl(m_hEnumControl, hControl, m_szCachePath) :
FindNextControl(m_hEnumControl, hControl));
if (pceltFetched)
*pceltFetched = (lres == ERROR_SUCCESS ? 1 : 0);
if (lres != ERROR_SUCCESS)
goto EXIT_NEXT;
pcpidl = CreateControlPidl(m_pMalloc, hControl);
if (pcpidl == NULL)
{
lres = ERROR_NOT_ENOUGH_MEMORY;
goto EXIT_NEXT;
}
m_bEnumStarted = TRUE;
rgelt[0] = (LPITEMIDLIST)pcpidl;
EXIT_NEXT:
ReleaseControlHandle(hControl);
if (lres != ERROR_SUCCESS)
{
if (pcpidl != NULL)
{
m_pMalloc->Free(pcpidl);
pcpidl = NULL;
}
FindControlClose(m_hEnumControl);
m_bEnumStarted = FALSE;
rgelt[0] = NULL;
}
return HRESULT_FROM_WIN32(lres);
}
HRESULT CControlFolderEnum::Skip(ULONG celt)
{
DebugMsg(DM_TRACE, TEXT("cfe - Skip() called."));
return E_NOTIMPL;
}
HRESULT CControlFolderEnum::Reset()
{
DebugMsg(DM_TRACE, TEXT("cfe - Reset() called."));
return E_NOTIMPL;
}
HRESULT CControlFolderEnum::Clone(IEnumIDList **ppenum)
{
DebugMsg(DM_TRACE, TEXT("cfe - Clone() called."));
return E_NOTIMPL;
}