|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997.
//
// File: P I D L . C P P
//
// Contents: PIDL utility routines. This stuff is mainly copied from the
// existing Namespace extension samples and real code, since
// everyone and their gramma uses this stuff.
//
// Notes:
//
// Author: jeffspr 1 Oct 1997
//
//----------------------------------------------------------------------------
#include "pch.h"
#pragma hdrstop
#include "shlobj.h"
#include "shlobjp.h"
#include "pidlutil.h"
#if DBG
//+---------------------------------------------------------------------------
//
// Function: ILNext
//
// Purpose: Return the next PIDL in the list
//
// Arguments:
// pidl []
//
// Returns:
//
// Author: jeffspr 1 Oct 1997 (from brianwen)
//
// Notes:
//
LPITEMIDLIST ILNext(LPCITEMIDLIST pidl) { if (pidl) { pidl = (LPITEMIDLIST) ((BYTE *)pidl + pidl->mkid.cb); }
return (LPITEMIDLIST)pidl; }
//+---------------------------------------------------------------------------
//
// Function: ILIsEmpty
//
// Purpose: Is this PIDL empty
//
// Arguments:
// pidl []
//
// Returns:
//
// Author: jeffspr 1 Oct 1997 (from brianwen)
//
// Notes:
//
BOOL ILIsEmpty(LPCITEMIDLIST pidl) { return (!pidl || !pidl->mkid.cb);
} #endif // #if DBG
//+---------------------------------------------------------------------------
//
// Function: ILCreate
//
// Purpose: Create a PIDL
//
// Arguments:
// cbSize []
//
// Returns:
//
// Author: jeffspr 1 Oct 1997 (from brianwen)
//
// Notes:
//
LPITEMIDLIST ILCreate(DWORD dwSize) { LPITEMIDLIST pidl = (LPITEMIDLIST) SHAlloc(dwSize);
return pidl; }
VOID FreeIDL(LPITEMIDLIST pidl) { Assert(pidl);
SHFree(pidl); }
//+---------------------------------------------------------------------------
//
// Function: ILIsSingleID
//
// Purpose: Returns TRUE if the idlist has just one ID in it.
//
// Arguments:
// pidl []
//
// Returns:
//
// Author: jeffspr 1 Oct 1997 (from brianwen)
//
// Notes:
//
BOOL ILIsSingleID(LPCITEMIDLIST pidl) { if (pidl == NULL) return FALSE;
return (pidl->mkid.cb == 0 || ILNext(pidl)->mkid.cb == 0); }
//+---------------------------------------------------------------------------
//
// Function: ILGetCID
//
// Purpose: Returns the number of ID's in the list.
//
// Arguments:
// pidl []
//
// Returns:
//
// Author: jeffspr 1 Oct 1997 (from brianwen)
//
// Notes:
//
UINT ILGetCID(LPCITEMIDLIST pidl) { UINT cid = 0;
while (!ILIsEmpty(pidl)) { ++ cid; pidl = ILNext(pidl); }
return cid; }
//+---------------------------------------------------------------------------
//
// Function: ILGetSizeCID
//
// Purpose: Get the length of the first cid items in a pidl.
//
// Arguments:
// pidl []
// cid []
//
// Returns:
//
// Author: jeffspr 1 Oct 1997 (from brianwen)
//
// Notes:
//
UINT ILGetSizeCID(LPCITEMIDLIST pidl, UINT cid) { UINT cbTotal = 0;
if (pidl) { cbTotal += sizeof(pidl->mkid.cb); // Null terminator
while (cid && !ILIsEmpty(pidl)) { cbTotal += pidl->mkid.cb; pidl = ILNext(pidl); -- cid; } }
return cbTotal; }
//+---------------------------------------------------------------------------
//
// Function: CloneIDLFirstCID
//
// Purpose: Make a new list consisting of only the first cid items on
// an existing list.
//
// Arguments:
// pidl []
// cid []
//
// Returns:
//
// Author: jeffspr 1 Oct 1997 (from brianwen)
//
// Notes:
//
LPITEMIDLIST CloneIDLFirstCID(LPCITEMIDLIST pidl, UINT cid) { Assert((INT)cid >= 0);
UINT cb = ILGetSizeCID(pidl, cid); LPITEMIDLIST pidlRet = (LPITEMIDLIST) SHAlloc(cb);
if (pidlRet) { // Notes: no need to zero-init.
// Also, do not copy the NULL terminator.
memcpy (pidlRet, pidl, cb - sizeof(pidl->mkid.cb));
LPITEMIDLIST pidlTerm = pidlRet;
// Cannot test for NULL terminator, we have not terminated
// the list yet.
//
while (cid) { pidlTerm = ILNext(pidlTerm); -- cid; }
pidlTerm->mkid.cb = 0; }
return pidlRet; }
//+---------------------------------------------------------------------------
//
// Function: ILSkipCID
//
// Purpose: Skips the first cid items in a pidl.
//
// Arguments:
// pidl []
// cid []
//
// Returns:
//
// Author: jeffspr 1 Oct 1997 (from brianwen)
//
// Notes:
//
LPITEMIDLIST ILSkipCID(LPCITEMIDLIST pidl, UINT cid) { Assert((INT)cid >= 0);
while (cid && !ILIsEmpty(pidl)) { pidl = ILNext(pidl); -- cid; }
return (LPITEMIDLIST)pidl; }
#if 0
BOOL ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) { if (FSetupGlobalShellFolders()) { LPSHELLFOLDER psfDesktop = (LPSHELLFOLDER) PvGlobGet (ipsfDesktop); if (psfDesktop) { VERIFYPTR(pidl1, FALSE); VERIFYPTR(pidl2, FALSE);
return psfDesktop->CompareIDs(0, pidl1, pidl2) == ResultFromShort(0); } } return FALSE; } #endif
//+---------------------------------------------------------------------------
//
// Function: CloneIDL
//
// Purpose: Clone an IDL (return a duplicate)
//
// Arguments:
// pidl []
//
// Returns:
//
// Author: jeffspr 1 Oct 1997 (from brianwen)
//
// Notes:
//
LPITEMIDLIST CloneIDL(LPCITEMIDLIST pidl) { UINT cb = 0; LPITEMIDLIST pidlRet = NULL;
if (pidl) { cb = ILGetSize(pidl);
pidlRet = (LPITEMIDLIST) SHAlloc(cb); if (pidlRet) { memcpy(pidlRet, pidl, cb); } }
return pidlRet; }
//+---------------------------------------------------------------------------
//
// Function: CloneRgIDL
//
// Purpose: Clone a pidl array
//
// Arguments:
// rgpidl [in] PIDL array to clone
// cidl [in] Count of the pidl array
// fUseCache [in] If TRUE, generate the returned IDL from the cache
// fAllowNonCacheItems [in] Use old version of pidl if cached version non available
// pppidl [out] Return pointer for pidl array
//
// Returns:
//
// Author: jeffspr 22 Oct 1997
//
// Notes:
//
/*
HRESULT HrCloneRgIDL( LPCITEMIDLIST * rgpidl, ULONG cidl, BOOL fUseCache, BOOL fAllowNonCacheItems, LPITEMIDLIST ** pppidl, ULONG * pcidl) { HRESULT hr = NOERROR; LPITEMIDLIST * rgpidlReturn = NULL; ULONG irg = 0; ULONG cidlCopied = 0;
Assert(pppidl); Assert(pcidl); Assert(rgpidl);
if (!rgpidl || !cidl) { hr = E_INVALIDARG; goto Exit; } else { // Alloc the return buffer
//
rgpidlReturn = (LPITEMIDLIST *) SHAlloc(cidl * sizeof(LPITEMIDLIST)); if (!rgpidlReturn) { hr = E_OUTOFMEMORY; goto Exit; } else { // Clone all elements within the passed in PIDL array
//
for (irg = 0; irg < cidl; irg++) { if (rgpidl[irg]) { if (fUseCache) { PCONNLISTENTRY pcle = NULL; PCONFOLDPIDL pcfp = (PCONFOLDPIDL) rgpidl[irg];
hr = g_ccl.HrFindConnectionByGuid(&(pcfp->guidId), &pcle); if (hr == S_OK) { Assert(pcle); Assert(pcle->pccfe);
// Copy to the return pidl array.
hr = HrConFoldEntryToPidl(pcle->pccfe, &(rgpidlReturn[cidlCopied++])); if (FAILED(hr)) goto Exit; } else { TraceTag(ttidShellFolder, "HrCloneRgIDL: Connection find returned: 0x%08x", hr);
if (hr == S_FALSE) { if (fAllowNonCacheItems) { TraceTag(ttidShellFolder, "HrCloneRgIDL: Connection not found in cache, " "using non-cache item");
rgpidlReturn[cidlCopied++] = CloneIDL((LPITEMIDLIST)rgpidl[irg]); if (!rgpidlReturn[irg]) { hr = E_OUTOFMEMORY; goto Exit; } } else { TraceTag(ttidShellFolder, "HrCloneRgIDL: Connection not found in cache. " "Dropping item from array"); } } else { AssertSz(FALSE, "HrCloneRgIDL: Connection find HR_FAILED"); } } } else { // Clone this element in the PIDL array
//
rgpidlReturn[cidlCopied++] = CloneIDL ((LPITEMIDLIST) rgpidl[irg]); if (!rgpidlReturn[irg]) { hr = E_OUTOFMEMORY; goto Exit; } } } else { // Make sure that we don't try to delete bogus data later.
//
rgpidlReturn[cidlCopied++] = NULL;
AssertSz(FALSE, "Bogus element in the rgpidl in HrCloneRgIDL"); hr = E_INVALIDARG; goto Exit; } } } }
Exit: if (FAILED(hr)) { // Free the already-allocated IDLISTs
//
ULONG irgT = 0;
for (irgT = 0; irgT < irg; irgT++) { if (rgpidlReturn[irgT]) { FreeIDL(rgpidlReturn[irgT]); } }
SHFree(rgpidlReturn); *pppidl = NULL; } else { // Fill in the return var.
//
*pppidl = rgpidlReturn; *pcidl = cidlCopied; }
TraceHr(ttidError, FAL, hr, FALSE, "HrCloneRgIDL"); return hr;
} // CloneRgIDL
*/
//+---------------------------------------------------------------------------
//
// Function: FreeRgIDL
//
// Purpose: Free a PIDL array
//
// Arguments:
// cidl [in] Size of PIDL array
// apidl [in] Pointer to the array itself.
//
// Returns:
//
// Author: jeffspr 27 Oct 1997
//
// Notes:
//
VOID FreeRgIDL( UINT cidl, LPITEMIDLIST * apidl) { if (apidl) { for (UINT i = 0; i < cidl; i++) { FreeIDL(apidl[i]); }
SHFree(apidl); } }
|