|
|
// ****************************************************************************
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 2000.
//
// File: C F P I D L . C P P
//
// Contents: Connections Folder structures and classes.
//
// Author: jeffspr 11 Nov 1997
//
// ****************************************************************************
#include "pch.h"
#pragma hdrstop
#include "ncperms.h"
#include "ncras.h"
#include "initguid.h"
#include "foldinc.h" // Standard shell\folder includes
#include "ncnetcon.h"
#include "ncmisc.h"
extern CRITICAL_SECTION g_csPidl;
BOOL fIsConnectedStatus(IN const NETCON_STATUS ncs) { switch (ncs) { case NCS_CONNECTED: case NCS_AUTHENTICATING: case NCS_AUTHENTICATION_FAILED: case NCS_AUTHENTICATION_SUCCEEDED: case NCS_CREDENTIALS_REQUIRED: return TRUE; default: return FALSE; } }
// ****************************************************************************
//
// Member: CConFoldEntry::CConFoldEntry
//
// Purpose: Constructor for CConFoldEntry
//
// Arguments:
// (none)
//
// Returns:
//
// Author: jeffspr 11 Nov 1997
// ****************************************************************************
CConFoldEntry::CConFoldEntry() throw() { m_bDirty = TRUE; TraceFileFunc(ttidConFoldEntry);
// Need to clear out the pointers, otherwise clear() will AV
m_pszName = NULL; m_pszDeviceName = NULL; m_pbPersistData = NULL; m_pszPhoneOrHostAddress = NULL; clear(); }
CConFoldEntry::CConFoldEntry(IN const CConFoldEntry& ConFoldEntry) throw() // NULL on failure
{ TraceFileFunc(ttidConFoldEntry); m_bDirty = TRUE; if (!ConFoldEntry.empty()) { HRESULT hr = HrDupFolderEntry(ConFoldEntry); if (FAILED(hr)) { clear(); } } else { // Need to clear out the pointers, otherwise clear() will AV
m_pszName = NULL; m_pszDeviceName = NULL; m_pbPersistData = NULL; m_pszPhoneOrHostAddress = NULL; clear(); } }
CConFoldEntry& CConFoldEntry::operator =(const CConFoldEntry& ConFoldEntry) // NULL on failure
{ TraceFileFunc(ttidConFoldEntry); m_bDirty = TRUE; if (!ConFoldEntry.empty()) { HRESULT hr = HrDupFolderEntry(ConFoldEntry); if (FAILED(hr)) { clear(); } } else { clear(); } return *this; }
// ****************************************************************************
//
// Member: CConFoldEntry::~CConFoldEntry
//
// Purpose: Destructor for CConFoldEntry
//
// Arguments:
// (none)
//
// Returns:
//
// Author: jeffspr 11 Nov 1997
// ****************************************************************************
CConFoldEntry::~CConFoldEntry() throw() { TraceFileFunc(ttidConFoldEntry); clear(); }
// ****************************************************************************
//
// Member: CConFoldEntry::SetDeviceName
//
// Purpose: Set the name of the device used by this connection
//
// Arguments:
// pszDeviceName - New device name (NULL is valid)
//
// Returns:
//
// Author: deonb 2000
// ****************************************************************************
HRESULT CConFoldEntry::SetDeviceName(IN LPCWSTR pszDeviceName) { HRESULT hr = S_OK; PWSTR pszOld = m_pszDeviceName; m_bDirty = TRUE; if (pszDeviceName) { // Only change the text is the text is actually different
//
if ((NULL == GetDeviceName()) || wcscmp(pszDeviceName, GetDeviceName())) { hr = HrDupeShellString(pszDeviceName, &m_pszDeviceName); } else { // NOTE: In this one case, nothing change so there is
// nothing to free so short circut the clean-up below
//
pszOld = NULL; hr = S_OK; } } else { hr = HrDupeShellString(L"", &m_pszDeviceName); } // Free the old string
//
if (SUCCEEDED(hr) && pszOld) { SHFree(pszOld); } TraceHr(ttidError, FAL, hr, FALSE, "CConFoldEntry::HrSetDeviceName"); return hr; }
// ****************************************************************************
//
// Member: CConFoldEntry::SetPhoneOrHostAddress
//
// Purpose: Set the name of the device used by this connection
//
// Arguments:
// pszPhoneOrHostAddress - New phone or host address (NULL is valid)
//
// Returns:
//
// Author: deonb 2000
// ****************************************************************************
HRESULT CConFoldEntry::SetPhoneOrHostAddress(IN LPCWSTR pszPhoneOrHostAddress) { HRESULT hr = S_OK; PWSTR pszOld = m_pszPhoneOrHostAddress; m_bDirty = TRUE; if (pszPhoneOrHostAddress) { // Only change the text is the text is actually different
//
if ((NULL == GetPhoneOrHostAddress()) || wcscmp(pszPhoneOrHostAddress, GetPhoneOrHostAddress())) { hr = HrDupeShellString(pszPhoneOrHostAddress, &m_pszPhoneOrHostAddress); } else { // NOTE: In this one case, nothing change so there is
// nothing to free so short circut the clean-up below
//
pszOld = NULL; hr = S_OK; } } else { hr = HrDupeShellString(L"", &m_pszPhoneOrHostAddress); } // Free the old string
//
if (SUCCEEDED(hr) && pszOld) { SHFree(pszOld); } TraceHr(ttidError, FAL, hr, FALSE, "CConFoldEntry::HrSetDeviceName"); return hr; }
// ****************************************************************************
//
// Member: CConFoldEntry::SetName
//
// Purpose: Set the name of the connection
//
// Arguments:
// pszName - New connection name (NULL is valid)
//
// Returns:
//
// Author: deonb 2000
// ****************************************************************************
HRESULT CConFoldEntry::SetName(IN LPCWSTR pszName) { HRESULT hr = S_OK; PWSTR pszOld = m_pszName; m_bDirty = TRUE; if (pszName) { // Only change the text is the text is actually different
//
if ((NULL == GetName()) || wcscmp(pszName, GetName())) { hr = HrDupeShellString(pszName, &m_pszName); } else { pszOld = NULL; hr = S_OK; } } else { PWSTR pszLoad = NULL; if (GetWizard() == WIZARD_MNC) { pszLoad = (PWSTR) SzLoadIds(IDS_CONFOLD_WIZARD_DISPLAY_NAME); } else if (GetWizard() == WIZARD_HNW) { pszLoad = (PWSTR) SzLoadIds(IDS_CONFOLD_HOMENET_WIZARD_DISPLAY_NAME); } // ISSUE: Change this to use c_szEmpty
//
hr = HrDupeShellString(pszLoad ? pszLoad : L"", &m_pszName); Assert(GetName()); } // Free the old string
//
if (SUCCEEDED(hr) && pszOld) { SHFree(pszOld); } TraceHr(ttidError, FAL, hr, FALSE, "CConFoldEntry::HrSetConnectionName"); return hr; }
// ****************************************************************************
//
// Member: CConFoldEntry::HrInitData
//
// Purpose: Initialize the CConFoldEntry data. Not all fields are
// required at this time, though they will most likely be
// required at some point during the life of the object.
//
// Arguments:
// wizWizard [in] Wizard type?
// ncm [in] Connection type
// ncs [in] Connection status
// pclsid [in] Pointer to CLSID of the connection
// pguidId [in] Pointer to unique GUID for the connection
// dwCharacteristics [in] Connection characteristics
// pbPersistData [in] Persistant data for this connection
// ulPersistSize [in] Size of the persist data blob
// pszName [in] Name of the connection
// pszDeviceName [in] Name of the connection's device
//
// Returns: S_OK or valid OLE return code.
//
// Author: deonb 2000
// ****************************************************************************
HRESULT CConFoldEntry::HrInitData(IN const WIZARD wizWizard, IN const NETCON_MEDIATYPE ncm, IN const NETCON_SUBMEDIATYPE ncsm, IN const NETCON_STATUS ncs, IN const CLSID * pclsid, IN LPCGUID pguidId, IN const DWORD dwCharacteristics, IN const BYTE * pbPersistData, IN const ULONG ulPersistSize, IN LPCWSTR pszName, IN LPCWSTR pszDeviceName, IN LPCWSTR pszPhoneOrHostAddress) { TraceFileFunc(ttidConFoldEntry); HRESULT hr = S_OK; // Initialize the internal data
//
m_bDirty = TRUE; m_wizWizard = wizWizard; m_ncm = ncm; m_ncs = ncs; m_dwCharacteristics = dwCharacteristics;;
BOOL fOldEapolStatus = ( (ncsm == NCSM_CM) && (ncm == NCM_LAN) ) // NCSM_CM used to be NCM_AUTHENTICATING
|| (ncsm > NCSM_CM); // E.g. NCM_AUTHENTICATION_SUCCEEDED etc.
if (!fOldEapolStatus) { m_ncsm = ncsm; } else { // ISSUE: This is for the migration of EAPOL state out off our PIDL
// This should be taken out after the no-prior-upgrades RC1 build is released.
if (NCM_LAN == ncm) { m_ncsm = NCSM_LAN; // If all else file, we'll pretend to be a normal LAN card.
CIntelliName inName(NULL, NULL); NETCON_MEDIATYPE ncmTmp; NETCON_SUBMEDIATYPE ncsmTmp;
// Try get the status from the OID or Bindings
HRESULT hrT = inName.HrGetPseudoMediaTypes(*pguidId, &ncmTmp, &ncsmTmp); if (SUCCEEDED(hrT)) { m_ncsm = ncsmTmp; } else { // Ok. That didn't work. Try the connections list next.
if (g_ccl.IsInitialized()) { ConnListEntry cle; hrT = g_ccl.HrFindConnectionByGuid(pguidId, cle); if (S_OK == hrT) { m_ncsm = cle.ccfe.GetNetConSubMediaType(); } }
} } else { m_ncsm = NCSM_NONE; } }
if (pclsid) { m_clsid = *pclsid; } else { AssertSz(wizWizard != WIZARD_NOT_WIZARD, "If you're not a wizard, you must give me a CLSID for the class!"); } if (pguidId) { m_guidId = *pguidId; }
AssertSz(pguidId, "You must give me a GUID for the object!"); // Copy the persist buffer
//
if (pbPersistData) { LPBYTE bufTemp = (BYTE *) SHAlloc(ulPersistSize); if (!bufTemp) { SetPersistData(NULL, 0); hr = E_OUTOFMEMORY; goto Exit; } CopyMemory(bufTemp, pbPersistData, ulPersistSize); SetPersistData(bufTemp, ulPersistSize); } else { AssertSz(wizWizard != WIZARD_NOT_WIZARD, "If you're not a wizard, you must give me a pbPersistData for the object!"); SetPersistData(NULL, 0); }
// Copy the device name
//
hr = SetDeviceName(pszDeviceName); if (SUCCEEDED(hr)) { // Copy the name
//
hr = SetName(pszName); if (SUCCEEDED(hr)) { hr = SetPhoneOrHostAddress(pszPhoneOrHostAddress); } }
Exit: TraceHr(ttidError, FAL, hr, FALSE, "CConFoldEntry::HrInitData"); return hr; }
// ****************************************************************************
//
// Member: CConFoldEntry::UpdateData
//
// Purpose: Modify the values in a CConFoldEntry
//
// Arguments:
// DWORD dwChangeFlags
// NETCON_MEDIATYPE MediaType
// NETCON_STATUS Status
// DWORD dwCharacteristics
// PWSTR pszName
// PWSTR pszDeviceName
//
// Returns: HRESULT
//
// Author: scottbri 10 Nov 1998
// ****************************************************************************
HRESULT CConFoldEntry::UpdateData( IN const DWORD dwChangeFlags, IN const NETCON_MEDIATYPE MediaType, IN const NETCON_SUBMEDIATYPE SubMediaType, IN const NETCON_STATUS Status, IN const DWORD dwCharacteristics, IN PCWSTR pszName, IN PCWSTR pszDeviceName, IN PCWSTR pszPhoneOrHostAddress) { TraceFileFunc(ttidConFoldEntry); HRESULT hr = S_OK; HRESULT hrTmp; m_bDirty = TRUE; if (dwChangeFlags & CCFE_CHANGE_MEDIATYPE) { SetNetConMediaType(MediaType); } if (dwChangeFlags & CCFE_CHANGE_SUBMEDIATYPE) { SetNetConSubMediaType(SubMediaType); } if (dwChangeFlags & CCFE_CHANGE_STATUS) { SetNetConStatus(Status); } if (dwChangeFlags & CCFE_CHANGE_CHARACTERISTICS) { SetCharacteristics(dwCharacteristics); }
if (dwChangeFlags & CCFE_CHANGE_NAME) { hrTmp = SetName(pszName); if (FAILED(hrTmp)) { hr = hrTmp; } } if (dwChangeFlags & CCFE_CHANGE_DEVICENAME) { hrTmp = SetDeviceName(pszDeviceName); if (FAILED(hrTmp)) { hr = hrTmp; } } if (dwChangeFlags & CCFE_CHANGE_PHONEORHOSTADDRESS) { hrTmp = SetPhoneOrHostAddress(pszPhoneOrHostAddress); if (FAILED(hrTmp)) { hr = hrTmp; } } TraceHr(ttidError, FAL, hr, FALSE, "CConFoldEntry::UpdateData"); return hr; }
// ****************************************************************************
//
// Member: CConFoldEntry::HrDupFolderEntry
//
// Purpose: Duplicate a connection folder entry.
//
// Arguments:
// pccfe The source folder entry to dup from
//
// Returns:
//
// Author: tongl 9/3/98
// ****************************************************************************
HRESULT CConFoldEntry::HrDupFolderEntry(const CConFoldEntry& ccfe) { TraceFileFunc(ttidConFoldEntry); m_bDirty = TRUE; Assert(!ccfe.empty()); clear(); return HrInitData( ccfe.GetWizard(), ccfe.GetNetConMediaType(), ccfe.GetNetConSubMediaType(), ccfe.GetNetConStatus(), &(ccfe.GetCLSID()), &(ccfe.GetGuidID()), ccfe.GetCharacteristics(), ccfe.GetPersistData(), ccfe.GetPersistSize(), ccfe.GetName(), ccfe.GetDeviceName(), ccfe.GetPhoneOrHostAddress()); }
// ****************************************************************************
//
// Member: CConFoldEntry::FShouldHaveTrayIconDisplayed
//
// Purpose: Return TRUE if this entry should have a tray icon displayed.
//
// Arguments:
// (none)
//
// Returns: TRUE or FALSE.
//
// Author: shaunco 2 Nov 1998
// ****************************************************************************
BOOL CConFoldEntry::FShouldHaveTrayIconDisplayed() const throw() { // If we're in a failed state (!IsConnected) or in any 802.1x state
// or we're connected and have the correct bits turned on with the correct permissions
// then we should display the icon
//
return ( ( !IsConnected() ) || ( (NCS_AUTHENTICATING == GetNetConStatus()) || (NCS_AUTHENTICATION_FAILED == GetNetConStatus()) || (NCS_AUTHENTICATION_SUCCEEDED == GetNetConStatus()) || (NCS_CREDENTIALS_REQUIRED == GetNetConStatus()) ) ) || ( (NCS_CONNECTED == GetNetConStatus()) && ( (GetCharacteristics() & NCCF_SHOW_ICON) && (!GetWizard()) && FHasPermission(NCPERM_Statistics) ) ); }
// ****************************************************************************
// Function:
//
// Purpose: Translate from a pidl to a CConFoldEntry class object
//
// Arguments:
// pidl [in] PIDL from which to create
// ppccfe [out] Resultant CConFoldEntry object pointer
//
// Returns:
//
// Author: jeffspr 11 Nov 1997
// ****************************************************************************
// ****************************************************************************
//
// Function: HrCreateConFoldPidlInternal
//
// Purpose: Utility function for creating new Connections Folder PIDLs.
// This function is primarily called from HrCreateConFoldPidl,
// but can also be called directly by those that have already
// loaded the properties and persist data.
//
// Arguments:
// pProps [in] From GetProperties
// pbBuf [in] The persist buffer
// ulBufSize [in] Size of the persist buffer
// szPhoneOrHostAddress [in] Phone or Host Address
// ppidl [out] Return pointer for the resultant pidl
//
// Returns:
//
// Author: jeffspr 27 Aug 1998
// ****************************************************************************
HRESULT HrCreateConFoldPidlInternal(IN const NETCON_PROPERTIES* pProps, IN const BYTE * pbBuf, IN ULONG ulBufSize, IN LPCWSTR szPhoneOrHostAddress, OUT PCONFOLDPIDL & pidl) { HRESULT hr = S_OK; CONFOLDENTRY ccfe; // Trace the useful info
//
TraceTag(ttidShellFolder, "Enum: %S, Ncm: %d, Ncs: %d, Char: 0x%08x " "(Show: %d, Del: %d, All: %d), Dev: %S", (pProps->pszwName) ? pProps->pszwName : L"null", pProps->MediaType, pProps->Status, pProps->dwCharacter, ((pProps->dwCharacter & NCCF_SHOW_ICON) > 0), ((pProps->dwCharacter & NCCF_ALLOW_REMOVAL) > 0), ((pProps->dwCharacter & NCCF_ALL_USERS) > 0), (pProps->pszwDeviceName) ? pProps->pszwDeviceName : L"null"); // Init the CConFoldEntry from the data that we've retrieved.
//
hr = ccfe.HrInitData(WIZARD_NOT_WIZARD, pProps->MediaType, NCSM_NONE, pProps->Status, &pProps->clsidThisObject, &pProps->guidId, pProps->dwCharacter, pbBuf, ulBufSize, pProps->pszwName, pProps->pszwDeviceName, szPhoneOrHostAddress); if (FAILED(hr)) { TraceHr(ttidShellFolder, FAL, hr, FALSE, "ccfe.HrInitData failed for " "non-wizard"); goto Exit; } // Translate into the actual pidl
//
hr = ccfe.ConvertToPidl(pidl); if (FAILED(hr)) { TraceHr(ttidShellFolder, FAL, hr, FALSE, "ConvertToPidl failed for non-wizard"); } Exit: TraceHr(ttidError, FAL, hr, FALSE, "HrCreateConFoldPidlInternal"); return hr; }
// ****************************************************************************
//
// Function: HrCreateConFoldPidl
//
// Purpose: Utility function for creating new Connections Folder PIDLs.
//
// Arguments:
// wizWizard [in] Is this PIDL for a wizard?
// pNetCon [in] INetConnection interface from the enumerator
// ppidl [out] Return pointer for the new pidl
//
// Returns: S_OK or valid OLE return code.
//
// Author: jeffspr 6 Oct 1997
//
// Notes: If the connection that you're adding is a real connection object
// (not the wizard) and you already have loaded the persist data and
// properties, you should call HrCreateConFoldPidlInternal directly
// ****************************************************************************
HRESULT HrCreateConFoldPidl(IN const WIZARD wizWizard, IN INetConnection * pNetCon, OUT PCONFOLDPIDL & ppidl) { HRESULT hr = S_OK; LPBYTE pbBuf = NULL; ULONG ulBufSize = 0; NETCON_PROPERTIES * pProps = NULL; CConFoldEntry ccfe; if (wizWizard == WIZARD_NOT_WIZARD) { Assert(pNetCon); hr = pNetCon->GetProperties (&pProps); if (FAILED(hr)) { TraceHr(ttidShellFolder, FAL, hr, FALSE, "pNetCon->GetProperties failed in " "CConnectionFolderEnum::HrCreateConFoldPidl"); goto Exit; } Assert (pProps); // Get the persist data from the connection
//
hr = HrGetConnectionPersistData(pNetCon, &pbBuf, &ulBufSize, NULL); if (FAILED(hr)) { TraceHr(ttidShellFolder, FAL, hr, FALSE, "HrGetConnectionPersistData failed in " "CConnectionFolderEnum::HrCreateConFoldPidl"); goto Exit; }
WCHAR szPhoneOrHostAddress[MAX_PATH]; wcscpy(szPhoneOrHostAddress, L" "); if ( (NCM_TUNNEL == pProps->MediaType) || (NCM_PHONE == pProps->MediaType) ) { HRESULT hrTmp; RASCON_INFO RasConInfo; if (SUCCEEDED(hr)) { hrTmp = HrRciGetRasConnectionInfo(pNetCon, &RasConInfo); if (SUCCEEDED(hrTmp)) { GetPrivateProfileString(RasConInfo.pszwEntryName, L"PhoneNumber", L" ", szPhoneOrHostAddress, MAX_PATH, RasConInfo.pszwPbkFile); RciFree(&RasConInfo); } } }
// Call the pre-read-data version of this function to actually pack the
// ccfe and insert.
//
hr = HrCreateConFoldPidlInternal(pProps, pbBuf, ulBufSize, szPhoneOrHostAddress, ppidl); if (FAILED(hr)) { goto Exit; } } else { GUID guidWiz; if (wizWizard == WIZARD_MNC) { guidWiz = GUID_MNC_WIZARD; } else { guidWiz = GUID_HNW_WIZARD; Assert(wizWizard == WIZARD_HNW); }
// Pack the CConFoldEntry data from the retrieved info
//
hr = ccfe.HrInitData(wizWizard, NCM_NONE, NCSM_NONE, NCS_DISCONNECTED, NULL, &guidWiz, 0, NULL, 0, NULL, NULL, NULL); if (FAILED(hr)) { TraceHr(ttidShellFolder, FAL, hr, FALSE, "ccfe.HrInitData failed for " "Wizard"); goto Exit; } // Translate into an actual pidl
//
hr = ccfe.ConvertToPidl(ppidl); if (FAILED(hr)) { TraceHr(ttidShellFolder, FAL, hr, FALSE, "ConvertToPidl failed for wizard"); } } Exit: MemFree(pbBuf); FreeNetconProperties(pProps); TraceHr(ttidError, FAL, hr, FALSE, "HrCreateConFoldPidl"); return hr; }
// ****************************************************************************
//
// Function: HrCreateConFoldPidl
//
// Purpose: Utility function for creating new Connections Folder PIDLs.
//
// Arguments:
// PropsEx [in] PropsEx structure
// ppidl [out] Return pointer for the new pidl
//
// Returns: S_OK or valid OLE return code.
//
// Author: deonb 26 Mar 2001
//
// Notes:
// ****************************************************************************
HRESULT HrCreateConFoldPidl(IN const NETCON_PROPERTIES_EX& PropsEx, OUT PCONFOLDPIDL & ppidl) { HRESULT hr = S_OK; NETCON_PROPERTIES * pProps = NULL; CConFoldEntry ccfe;
// Trace the useful info
//
TraceTag(ttidShellFolder, "Enum: %S, Ncm: %d, Ncs: %d, Char: 0x%08x " "(Show: %d, Del: %d, All: %d), Dev: %S", (PropsEx.bstrName) ? PropsEx.bstrName : L"null", PropsEx.ncMediaType, PropsEx.ncStatus, PropsEx.dwCharacter, ((PropsEx.dwCharacter & NCCF_SHOW_ICON) > 0), ((PropsEx.dwCharacter & NCCF_ALLOW_REMOVAL) > 0), ((PropsEx.dwCharacter & NCCF_ALL_USERS) > 0), (PropsEx.bstrDeviceName) ? PropsEx.bstrDeviceName : L"null");
// Init the CConFoldEntry from the data that we've retrieved.
//
hr = ccfe.HrInitData(WIZARD_NOT_WIZARD, PropsEx.ncMediaType, PropsEx.ncSubMediaType, PropsEx.ncStatus, &PropsEx.clsidThisObject, &PropsEx.guidId, PropsEx.dwCharacter, reinterpret_cast<const BYTE*>(PropsEx.bstrPersistData), SysStringByteLen(PropsEx.bstrPersistData), PropsEx.bstrName, PropsEx.bstrDeviceName, PropsEx.bstrPhoneOrHostAddress);
if (SUCCEEDED(hr)) { // Translate into the actual pidl
//
hr = ccfe.ConvertToPidl(ppidl); }
TraceHr(ttidShellFolder, FAL, hr, FALSE, "HrCreateConFoldPidl"); return hr; }
// ****************************************************************************
//
// Function: ConvertToPidlInCache
//
// Purpose: Determine whether a particular PIDL is in a format we support.
// If so but it is not in the CONFOLDPIDL format, then find a match
// in our cache and allocate a new pisl
//
// Arguments:
// pidl [] PIDL to test
// ppcfpRet PIDL converted to PCONFOLDPIDL, if required and it
// matches an existing connection in the cache
//
// Returns: NONE
//
// Author: tongl, 4 April, 1999
// ****************************************************************************
// ****************************************************************************
//
// Function: HrNetConFromPidl
//
// Purpose: Translate from a packed PIDL to a INetConnection pointer.
// Do this by converting to a ConFoldEntry and getting the
// pointer from there
//
// Arguments:
// pidl [in] Pidl that contains the connection persist data
// ppNetCon [out] INetConnection * return
//
// Returns:
//
// Author: jeffspr 11 Nov 1997
// ****************************************************************************
HRESULT HrNetConFromPidl(IN const PCONFOLDPIDL & pidl, OUT INetConnection ** ppNetCon) { HRESULT hr = S_OK; CONFOLDENTRY pccfe; Assert(ppNetCon); hr = pidl.ConvertToConFoldEntry(pccfe); if (SUCCEEDED(hr)) { Assert(!pccfe.empty()); hr = pccfe.HrGetNetCon(IID_INetConnection, reinterpret_cast<VOID**>(ppNetCon)); } // Free the CConFoldEntry class, if successfully created
//
TraceHr(ttidError, FAL, hr, FALSE, "HrNetConFromPidl"); return hr; }
// ****************************************************************************
//
// Member: CConFoldEntry::HrGetNetCon
//
// Purpose: Get the INetConnection pointer from the persisted data
//
// Arguments:
// riid Interface to query for
// ppv [] Return pointer for the interface
//
// Returns:
//
// Author: jeffspr 11 Nov 1997
// ****************************************************************************
HRESULT CConFoldEntry::HrGetNetCon(IN REFIID riid, IN VOID** ppv) const { HRESULT hr = HrGetConnectionFromPersistData( GetCLSID(), GetPersistData(), GetPersistSize(), riid, ppv); TraceHr(ttidError, FAL, hr, FALSE, "CConFoldEntry::HrGetNetCon"); return hr; }
// ****************************************************************************
// ****************************************************************************
//
// Member: PConfoldPidlVecFromItemIdListArray
//
// Purpose: Covert a LPCITEMIDLIST into a PIDL vector
//
// Arguments:
// apidl [in] LPCITEMIDLIST array of PIDLs
// dwPidlCount [in] Number of items in the array
// vecConfoldPidl [out] Vector of PIDLs
//
// Returns:
//
// Author: deonb 2000
// ****************************************************************************
HRESULT PConfoldPidlVecFromItemIdListArray(IN LPCITEMIDLIST * apidl, IN const DWORD dwPidlCount, OUT PCONFOLDPIDLVEC& vecConfoldPidl) { HRESULT hr = S_OK; if (NULL == apidl) { return S_FALSE; } LPCITEMIDLIST *tmpIdList = apidl; for (DWORD i = 0; i < dwPidlCount; i++) { PCONFOLDPIDL newPidl; hr = newPidl.InitializeFromItemIDList(*tmpIdList); if (SUCCEEDED(hr)) { vecConfoldPidl.push_back(newPidl); } else { break; } tmpIdList++; } return hr; }
#ifdef DBG_VALIDATE_PIDLS
inline BOOL IsValidPIDL(IN LPCITEMIDLIST pidl) throw() { CExceptionSafeLock esLock(&g_csPidl); if (NULL == pidl) { return TRUE; } if (IsBadReadPtr(pidl, sizeof(USHORT))) { AssertSz(FALSE, "invalid read pointer"); return FALSE; } else { if (IsBadReadPtr(pidl, pidl->mkid.cb) ) { AssertSz(FALSE, "invalid read buffer"); return FALSE; } else { if (0 == _ILNext(pidl)->mkid.cb || IsValidPIDL(_ILNext(pidl)) ) { return TRUE; } else { // Don't need to assert since called IsValidPidl would have asserted already
return FALSE; } } } return FALSE; } #endif
BOOL IsNullTerminatedW(LPCWSTR szString, DWORD dwMaxLen) { for (DWORD x = 0; x < dwMaxLen; x++) { if (szString[x] == L'\0') { return TRUE; } }
return FALSE; }
BOOL IsNullTerminatedA(LPCSTR szString, DWORD dwMaxLen) { for (DWORD x = 0; x < dwMaxLen; x++) { if (szString[x] == '\0') { return TRUE; } }
return FALSE; }
BOOL ConFoldPidl_v1::IsPidlOfThisType() const throw() { BOOL bValidPidl = FALSE;
if ( GetPidlType(reinterpret_cast<LPCITEMIDLIST>(this)) == PIDL_TYPE_V1 ) { #if defined (_X86_)
DWORD dwDataOffset = bData - reinterpret_cast<const BYTE *>(this); // Get bData offset;
DWORD dwPidlSize; dwPidlSize = dwDataOffset; dwPidlSize += ulPersistBufSize; dwPidlSize += ulStrNameSize; dwPidlSize += ulStrDeviceNameSize; dwPidlSize += sizeof(USHORT); // Terminating
if ( (uLeadId == CONFOLDPIDL_LEADID) && (uTrailId == CONFOLDPIDL_TRAILID) && (dwPidlSize <= iCB) // Calculated size <= handed PIDL size (Sometimes V1 PIDLs are shorter - hence not == a check.)
&& (ulStrNamePos == 0) // Name starts at 0
&& (ulPersistBufPos < iCB) // Persisted buffer starts before end of PIDL
&& (ulStrDeviceNamePos < iCB) // Devicename starts before end of PIDL
&& (ulPersistBufSize < iCB) // Persisted buffer size smaller than PIDL
&& (ulStrDeviceNameSize < iCB) // Devicename smaller than PIDL
&& (ulStrNameSize < iCB) // Name smaller than PIDL
&& (ulStrDeviceNamePos == ulStrNameSize) // Device name starts where name stops
&& (ulPersistBufPos == ulStrDeviceNamePos + ulStrDeviceNameSize) // Persisted buffer starts where DeviceName stops
&& (dwDataOffset + ulPersistBufPos + ulPersistBufSize <= iCB) // Persisted buffer ends before PIDL
&& (IsNullTerminatedW(PszGetNamePointer(), ulStrNameSize) ) // Name is zero terminated correctly
&& (IsNullTerminatedW(PszGetDeviceNamePointer(), ulStrDeviceNameSize) ) // Device name is zero terminated correctly
) { bValidPidl = TRUE; } #else
bValidPidl = TRUE; #endif
}
if (!bValidPidl) { TraceTag(ttidError, "Ignoring bad V1 pidl"); }
return bValidPidl; }
BOOL ConFoldPidl_v2::IsPidlOfThisType() const throw() { BOOL bValidPidl = FALSE;
if ( GetPidlType(reinterpret_cast<LPCITEMIDLIST>(this)) == PIDL_TYPE_V2 ) { #if defined (_X86_)
DWORD dwDataOffset = bData - reinterpret_cast<const BYTE *>(this); // Get bData offset;
DWORD dwPidlSize; dwPidlSize = dwDataOffset; dwPidlSize += ulPersistBufSize; dwPidlSize += ulStrNameSize; dwPidlSize += ulStrDeviceNameSize; dwPidlSize += ulStrPhoneOrHostAddressSize; dwPidlSize += sizeof(USHORT); // Terminating 0
if ( (uLeadId == CONFOLDPIDL_LEADID) && (uTrailId == CONFOLDPIDL_TRAILID) && (dwPidlSize <= iCB) // Calculated size <= handed PIDL size (Sometimes PIDLs imported from V1 are shorter - hence not == a check.)
&& (ulStrNamePos == 0) // Name starts at 0
&& (ulPersistBufPos < iCB) // Persisted buffer starts before end of PIDL
&& (ulStrDeviceNamePos < iCB) // Devicename starts before end of PIDL
&& (ulStrPhoneOrHostAddressPos < iCB) // Phone/Host starts before end of PIDL
&& (ulPersistBufSize < iCB) // Persisted buffer size smaller than PIDL
&& (ulStrDeviceNameSize < iCB) // Devicename smaller than PIDL
&& (ulStrNameSize < iCB) // Name smaller than PIDL
&& (ulStrDeviceNamePos == ulStrNameSize) // Device name starts where name stops
&& (ulPersistBufPos == ulStrDeviceNamePos + ulStrDeviceNameSize) // Persisted buffer starts where DeviceName stops
&& (ulStrPhoneOrHostAddressPos == ulPersistBufPos + ulPersistBufSize) // Phone/Host starts where Persisted buffer stop
&& (dwDataOffset + ulStrPhoneOrHostAddressPos + ulStrPhoneOrHostAddressSize <= iCB) // Phone/Host ends before PIDL
&& (IsNullTerminatedW(PszGetNamePointer(), ulStrNameSize)) // Name is zero terminated correctly
&& (IsNullTerminatedW(PszGetDeviceNamePointer(), ulStrDeviceNameSize)) // Device name is zero terminated correctly
&& (IsNullTerminatedW(PszGetPhoneOrHostAddressPointer(), ulStrPhoneOrHostAddressSize)) // Phone/host is zero terminated correctly
) { bValidPidl = TRUE; } #else
bValidPidl = TRUE; #endif
}
if (!bValidPidl) { TraceTag(ttidError, "Ignoring bad V2 pidl"); } return bValidPidl; }
BOOL ConFoldPidlFolder::IsPidlOfThisType() const throw() { // We can't tell if it's a PIDL_TYPE_FOLDER - this is shell internal
if ( GetPidlType(reinterpret_cast<LPCITEMIDLIST>(this)) == PIDL_TYPE_UNKNOWN ) { #ifdef DBG
if ( (dwLength != 0x14) || (dwId != 0x1f) ) { return FALSE; } #endif
return TRUE; } else { return FALSE; } }
BOOL ConFoldPidl98::IsPidlOfThisType(OUT BOOL* pReserved) const throw() { BOOL bValidPidl = FALSE;
if ( GetPidlType(reinterpret_cast<LPCITEMIDLIST>(this)) == PIDL_TYPE_98 ) { if (IsNullTerminatedA(szaName, min(cbSize, MAX_PATH))) // Name is zero terminated inside PIDL and smaller than MAX_PATH
{ bValidPidl = TRUE; } }
if (!bValidPidl) { TraceTag(ttidError, "Ignoring bad V98 pidl"); }
return bValidPidl; }
const DWORD CConFoldEntry::GetCharacteristics() const throw() { return m_dwCharacteristics; }
HRESULT CConFoldEntry::SetCharacteristics(IN const DWORD dwCharacteristics) { m_bDirty = TRUE; m_dwCharacteristics = dwCharacteristics; return S_OK; }
const GUID CConFoldEntry::GetGuidID() const throw() { return m_guidId; }
HRESULT CConFoldEntry::SetGuidID(IN const GUID guidId) { m_bDirty = TRUE; m_guidId = guidId; return S_OK; }
const CLSID CConFoldEntry::GetCLSID() const throw() { return m_clsid; }
HRESULT CConFoldEntry::SetCLSID(IN const CLSID clsid) { m_bDirty = TRUE; m_clsid = clsid; return S_OK; }
PCWSTR CConFoldEntry::GetName() const throw() { return m_pszName; }
HRESULT CConFoldEntry::SetPName(IN TAKEOWNERSHIP SHALLOCATED PWSTR pszName) { m_bDirty = TRUE; m_pszName = pszName; return S_OK; }
PCWSTR CConFoldEntry::GetDeviceName() const throw() { return m_pszDeviceName; }
HRESULT CConFoldEntry::SetPDeviceName(IN TAKEOWNERSHIP SHALLOCATED PWSTR pszDeviceName) { m_bDirty = TRUE; m_pszDeviceName = pszDeviceName; return S_OK; }
PCWSTR CConFoldEntry::GetPhoneOrHostAddress() const throw() { return m_pszPhoneOrHostAddress; }
HRESULT CConFoldEntry::SetPPhoneOrHostAddress(IN TAKEOWNERSHIP SHALLOCATED PWSTR pszPhoneOrHostAddress) { m_bDirty = TRUE; m_pszPhoneOrHostAddress = pszPhoneOrHostAddress; return S_OK; }
const NETCON_STATUS CConFoldEntry::GetNetConStatus() const throw() { return m_ncs; }
const BOOL CConFoldEntry::IsConnected() const throw() { return (m_ncs != NCS_MEDIA_DISCONNECTED) && (m_ncs != NCS_INVALID_ADDRESS); }
HRESULT CConFoldEntry::SetNetConStatus(IN const NETCON_STATUS ncs) { m_bDirty = TRUE; m_ncs = ncs; return S_OK; }
const NETCON_MEDIATYPE CConFoldEntry::GetNetConMediaType() const throw() { return m_ncm; }
HRESULT CConFoldEntry::SetNetConMediaType(IN const NETCON_MEDIATYPE ncm) { m_bDirty = TRUE; m_ncm = ncm; return S_OK; }
const NETCON_SUBMEDIATYPE CConFoldEntry::GetNetConSubMediaType() const throw() { return m_ncsm; }
HRESULT CConFoldEntry::SetNetConSubMediaType(IN const NETCON_SUBMEDIATYPE ncsm) { m_bDirty = TRUE; m_ncsm = ncsm; return S_OK; }
const WIZARD CConFoldEntry::GetWizard() const throw() { return m_wizWizard; }
HRESULT CConFoldEntry::SetWizard(IN const WIZARD wizWizard) { m_bDirty = TRUE; m_wizWizard = wizWizard; return S_OK; }
const BYTE * CConFoldEntry::GetPersistData() const throw() { return m_pbPersistData; }
const ULONG CConFoldEntry::GetPersistSize() const throw() { return m_ulPersistSize; }
HRESULT CConFoldEntry::SetPersistData(IN BYTE* TAKEOWNERSHIP SHALLOCATED pbPersistData, IN const ULONG ulPersistSize) { m_bDirty = TRUE; m_pbPersistData = pbPersistData; m_ulPersistSize = ulPersistSize; return S_OK; }
BOOL CConFoldEntry::empty() const throw() { if (GetWizard()) { return FALSE; } else { if (IsEqualGUID(GetCLSID(), GUID_NULL) ) { return TRUE; } else { return FALSE; } } }
void CConFoldEntry::clear() throw() { TraceFileFunc(ttidConFoldEntry); m_bDirty = TRUE; if (GetName()) { SHFree(m_pszName); m_pszName = NULL; } if (GetDeviceName()) { SHFree(m_pszDeviceName); m_pszDeviceName = NULL; } if (GetPhoneOrHostAddress()) { SHFree(m_pszPhoneOrHostAddress); m_pszPhoneOrHostAddress = NULL; } if (GetPersistData()) { SHFree(m_pbPersistData); m_pbPersistData = NULL; m_ulPersistSize = 0; } m_wizWizard = WIZARD_NOT_WIZARD; m_ncm = NCM_NONE; m_ncsm= NCSM_NONE; m_ncs = NCS_DISCONNECTED; m_dwCharacteristics = 0; m_clsid = GUID_NULL; m_guidId = GUID_NULL; }
LPITEMIDLIST CConFoldEntry::TearOffItemIdList() const throw() { PCONFOLDPIDL pidl; m_bDirty = TRUE; ConvertToPidl(pidl); return pidl.TearOffItemIdList(); }
HRESULT CConFoldEntry::InitializeFromItemIdList(IN LPCITEMIDLIST lpItemIdList) { PCONFOLDPIDL pidl; HRESULT hr = S_OK; m_bDirty = TRUE; hr = pidl.InitializeFromItemIDList(lpItemIdList); if (FAILED(hr)) { return hr; } hr = pidl.ConvertToConFoldEntry(*this); return hr; }
HRESULT CConFoldEntry::ConvertToPidl( OUT CPConFoldPidl<ConFoldPidl_v1>& pidl) const { TraceFileFunc(ttidConFoldEntry); HRESULT hr = S_OK; DWORD dwNameSize = 0; DWORD dwDeviceNameSize = 0; DWORD dwPidlSize = sizeof(ConFoldPidl_v1); // Initialize the PIDL byte count with the base size
Assert(!empty()); Assert(GetName()); Assert(GetDeviceName());
NETCFG_TRY
if (m_bDirty) { // Get the size of the name, and tack on a trailing NULL (since we now
// have something else in the buffer behind it.
//
dwNameSize = lstrlenW(GetName()) + 1; dwDeviceNameSize = lstrlenW(GetDeviceName()) + 1;
// Add the size of the string to the PIDL struct size. We don't need to include
// an extra byte for the string's terminating NULL because we've already
// included a WCHAR[1] in the struct.
//
dwPidlSize += ((dwNameSize) * sizeof(WCHAR)); dwPidlSize += ((dwDeviceNameSize) * sizeof(WCHAR)); // Tack of the length of the persist buffer
//
dwPidlSize += GetPersistSize(); // Allocate the PIDL.
//
hr = pidl.ILCreate(dwPidlSize + sizeof(USHORT)); // Terminating 0 for the PIDL
if (SUCCEEDED(hr)) { PWSTR pszName = NULL; PWSTR pszDeviceName = NULL; PWSTR pszPhoneOrHostAddress = NULL; // Fill in the pidl info.
//
pidl->wizWizard = GetWizard(); pidl->iCB = (WORD)dwPidlSize; // pidl->dwVersion = CONNECTIONS_FOLDER_IDL_VERSION_V1;
pidl->ncm = GetNetConMediaType(); pidl->ncs = GetNetConStatus(); pidl->uLeadId = CONFOLDPIDL_LEADID; pidl->uTrailId = CONFOLDPIDL_TRAILID; pidl->clsid = GetCLSID(); pidl->guidId = GetGuidID(); pidl->dwCharacteristics = GetCharacteristics(); // Fill in the name
//
pidl->ulStrNamePos = 0; // offset into the PIDL's pbBuf
pidl->ulStrNameSize = dwNameSize * sizeof(WCHAR); // in bytes
pszName = pidl->PszGetNamePointer(); lstrcpyW(pszName, GetName()); pszName[dwNameSize] = 0; // Fill in the device name, and set the offset info
//
pidl->ulStrDeviceNamePos = pidl->ulStrNamePos + pidl->ulStrNameSize; pidl->ulStrDeviceNameSize = dwDeviceNameSize * sizeof(WCHAR); // in bytes
pszDeviceName = pidl->PszGetDeviceNamePointer(); lstrcpyW(pszDeviceName, GetDeviceName()); pszDeviceName[dwDeviceNameSize] = 0; // Set the offset into the PIDL's pbBuf
//
pidl->ulPersistBufPos = pidl->ulStrDeviceNamePos + pidl->ulStrDeviceNameSize; // Fill in the persist buffer, if present (it won't be on a wizard)
//
if (GetPersistData()) { pidl->ulPersistBufSize = GetPersistSize(); CopyMemory(pidl->bData + pidl->ulPersistBufPos, GetPersistData(), GetPersistSize()); } else { // Since we're the wizard, there shouldn't be a buffer, so the size
// should always be passed in as 0.
//
Assert(GetPersistSize() == 0); pidl->ulPersistBufSize = 0; }
// Don't forget to terminate the list!
//
LPITEMIDLIST pidlTerminate; pidlTerminate = ILNext( pidl.GetItemIdList() ); pidlTerminate->mkid.cb = 0; } else { AssertSz(FALSE, "CConFoldEntry::ConvertToPidl is hosed"); hr = E_OUTOFMEMORY; } #ifdef DBG_VALIDATE_PIDLS
Assert(IsValidPIDL( pidl.GetItemIdList() )); #endif
Assert( pidl->IsPidlOfThisType() ) ; if (SUCCEEDED(hr)) { m_bDirty = FALSE; m_CachedV1Pidl = pidl; } } else { TraceTag(ttidShellFolder, "Using internally cached PIDL"); pidl = m_CachedV1Pidl; }
NETCFG_CATCH(hr)
TraceHr(ttidError, FAL, hr, FALSE, "CConFoldEntry::ConvertToPidl"); return hr; }
HRESULT CConFoldEntry::ConvertToPidl( OUT CPConFoldPidl<ConFoldPidl_v2>& pidl) const { TraceFileFunc(ttidConFoldEntry); HRESULT hr = S_OK; DWORD dwNameSize = 0; DWORD dwDeviceNameSize = 0; DWORD dwPhoneOrHostAddressSize = 0; DWORD dwPidlSize = sizeof(ConFoldPidl_v2); // Initialize the PIDL byte count with the base size
Assert(!empty()); Assert(GetName()); Assert(GetDeviceName()); Assert(GetPhoneOrHostAddress());
NETCFG_TRY if (m_bDirty) { // Get the size of the name, and tack on a trailing NULL (since we now
// have something else in the buffer behind it.
//
dwNameSize = lstrlenW(GetName()) + 1; dwDeviceNameSize = lstrlenW(GetDeviceName()) + 1; dwPhoneOrHostAddressSize = lstrlenW(GetPhoneOrHostAddress()) + 1; // Add the size of the string to the PIDL struct size. We don't need to include
// an extra byte for the string's terminating NULL because we've already
// included a WCHAR[1] in the struct.
//
dwPidlSize += ((dwNameSize) * sizeof(WCHAR)); dwPidlSize += ((dwDeviceNameSize) * sizeof(WCHAR)); dwPidlSize += ((dwPhoneOrHostAddressSize) * sizeof(WCHAR)); // Tack of the length of the persist buffer
//
dwPidlSize += GetPersistSize(); // Allocate the PIDL.
//
hr = pidl.ILCreate(dwPidlSize + sizeof(USHORT)); // Terminating 0 for the PIDL
if (SUCCEEDED(hr)) { PWSTR pszName = NULL; PWSTR pszDeviceName = NULL; PWSTR pszPhoneOrHostAddress = NULL; // Fill in the pidl info.
//
pidl->wizWizard = GetWizard(); pidl->iCB = (WORD)dwPidlSize; // pidl->dwVersion = CONNECTIONS_FOLDER_IDL_VERSION_V1;
pidl->ncm = GetNetConMediaType(); pidl->ncs = GetNetConStatus(); pidl->ncsm = GetNetConSubMediaType(); pidl->uLeadId = CONFOLDPIDL_LEADID; pidl->uTrailId = CONFOLDPIDL_TRAILID; pidl->clsid = GetCLSID(); pidl->guidId = GetGuidID(); pidl->dwCharacteristics = GetCharacteristics(); // Fill in the name
//
pidl->ulStrNamePos = 0; // offset into the PIDL's pbBuf
pidl->ulStrNameSize = dwNameSize * sizeof(WCHAR); // in bytes
pszName = pidl->PszGetNamePointer(); lstrcpyW(pszName, GetName()); pszName[dwNameSize] = 0; // Fill in the device name, and set the offset info
//
pidl->ulStrDeviceNamePos = pidl->ulStrNamePos + pidl->ulStrNameSize; pidl->ulStrDeviceNameSize = dwDeviceNameSize * sizeof(WCHAR); // in bytes
pszDeviceName = pidl->PszGetDeviceNamePointer(); lstrcpyW(pszDeviceName, GetDeviceName()); pszDeviceName[dwDeviceNameSize] = 0;
// Set the offset into the PIDL's pbBuf
//
pidl->ulPersistBufPos = pidl->ulStrDeviceNamePos + pidl->ulStrDeviceNameSize;
// Fill in the persist buffer, if present (it won't be on a wizard)
//
if (GetPersistData()) { pidl->ulPersistBufSize = GetPersistSize(); CopyMemory(pidl->bData + pidl->ulPersistBufPos, GetPersistData(), GetPersistSize()); } else { // Since we're the wizard, there shouldn't be a buffer, so the size
// should always be passed in as 0.
//
Assert(GetPersistSize() == 0); pidl->ulPersistBufSize = 0; } // Fill in the Phone Number & Host Address name, and set the offset info
//
pidl->ulStrPhoneOrHostAddressPos = pidl->ulPersistBufPos + pidl->ulPersistBufSize; // offset
pidl->ulStrPhoneOrHostAddressSize = dwPhoneOrHostAddressSize * sizeof(WCHAR); // in bytes
pszPhoneOrHostAddress = pidl->PszGetPhoneOrHostAddressPointer(); lstrcpyW(pszPhoneOrHostAddress, GetPhoneOrHostAddress()); pszPhoneOrHostAddress[dwPhoneOrHostAddressSize] = 0;
Assert( !lstrcmpW(pidl->PszGetNamePointer(), GetName()) ); Assert( !lstrcmpW(pidl->PszGetPhoneOrHostAddressPointer(), GetPhoneOrHostAddress()) ); Assert( !lstrcmpW(pidl->PszGetDeviceNamePointer(), GetDeviceName()) ); Assert( !memcmp(pidl->PbGetPersistBufPointer(), GetPersistData(), GetPersistSize()) ); // Don't forget to terminate the list!
//
LPITEMIDLIST pidlTerminate; pidlTerminate = ILNext( pidl.GetItemIdList() ); pidlTerminate->mkid.cb = 0; } else { AssertSz(FALSE, "CConFoldEntry::ConvertToPidl is hosed"); hr = E_OUTOFMEMORY; }
#ifdef DBG_VALIDATE_PIDLS
Assert(IsValidPIDL( pidl.GetItemIdList() )); #endif
Assert( pidl->IsPidlOfThisType() ) ; if (SUCCEEDED(hr)) { m_bDirty = FALSE; m_CachedV2Pidl = pidl; } } else { TraceTag(ttidShellFolder, "Using internally cached PIDL"); pidl = m_CachedV2Pidl; }
NETCFG_CATCH(hr)
TraceHr(ttidError, FAL, hr, FALSE, "CConFoldEntry::ConvertToPidl"); return hr; }
CONFOLDPIDLTYPE GetPidlType(IN LPCITEMIDLIST pidl) throw() { CONFOLDPIDLTYPE bRet = PIDL_TYPE_UNKNOWN; if (!pidl) { return bRet; } // V1 check
if (pidl->mkid.cb >= CBCONFOLDPIDLV1_MIN) { const UNALIGNED ConFoldPidl_v1* pcfp = reinterpret_cast<const ConFoldPidl_v1*>(pidl); if ( (pcfp->iCB >= CBCONFOLDPIDLV1_MIN) && (pcfp->iCB <= CBCONFOLDPIDLV1_MAX)) { if (pcfp->uLeadId == CONFOLDPIDL_LEADID && pcfp->uTrailId == CONFOLDPIDL_TRAILID) { if (pcfp->dwVersion == ConFoldPidl_v1::CONNECTIONS_FOLDER_IDL_VERSION) { bRet = PIDL_TYPE_V1; return bRet; } } } } // V2 check
if (pidl->mkid.cb >= CBCONFOLDPIDLV2_MIN) { const UNALIGNED ConFoldPidl_v2* pcfp = reinterpret_cast<const ConFoldPidl_v2 *>(pidl); if ( (pcfp->iCB >= CBCONFOLDPIDLV2_MIN) && (pcfp->iCB <= CBCONFOLDPIDLV2_MAX)) { if (pcfp->uLeadId == CONFOLDPIDL_LEADID && pcfp->uTrailId == CONFOLDPIDL_TRAILID) { if (pcfp->dwVersion == ConFoldPidl_v2::CONNECTIONS_FOLDER_IDL_VERSION) { bRet = PIDL_TYPE_V2; return bRet; } } } } // 98 Check
if (pidl->mkid.cb >= CBCONFOLDPIDL98_MIN) { const UNALIGNED ConFoldPidl98* pcfp = reinterpret_cast<const ConFoldPidl98 *>(pidl); if ((pcfp->cbSize >= CBCONFOLDPIDL98_MIN) && (pcfp->cbSize <= CBCONFOLDPIDL98_MAX)) { if ((SOF_REMOTE == pcfp->uFlags) || (SOF_NEWREMOTE == pcfp->uFlags) || (SOF_MEMBER == pcfp->uFlags)) { if (pcfp->nIconIndex >= 0) { bRet = PIDL_TYPE_98; return bRet; } } } } return bRet; }
HRESULT ConFoldPidl_v1::ConvertToConFoldEntry(OUT CConFoldEntry& ccfe) const { HRESULT hr = S_OK; Assert(this); if (!this) { return E_UNEXPECTED; } #if ( defined (MMMDBG) && defined ( _X86_ ) )
if ( (g_ccl.m_csMain.OwningThread == (HANDLE)GetCurrentThreadId()) && (g_ccl.m_csMain.LockCount != -1) ) { AssertSz(NULL, ".ConvertToConFoldEntry is called while the thread is owning g_ccl's Critical section. \r\n" "This may deadlock since .ConvertToConFoldEntry needs to marshall COM calls to other threads \r\n\r\n" "To Fix: Make a copy of ccfe from the pidl and Release the lock before calling .ConvertToConFoldEntry."); } #endif
// hr = ConvertToPidlInCache(*this, pcfp); // NOT REQUIRED. WE KNOW THIS IS A V1 PIDL!
// Initialize the data from the pidl
hr = ccfe.HrInitData(wizWizard, ncm, NCSM_NONE, ncs, &clsid, &guidId, dwCharacteristics, PbGetPersistBufPointer(), ulPersistBufSize, PszGetNamePointer(), PszGetDeviceNamePointer(), NULL /*PszGetPhoneOrHostAddressPointer()*/); if (FAILED(hr)) { TraceHr(ttidShellFolder, FAL, hr, FALSE, "Failed in call to pcfe->HrInitData in ConvertToConFoldEntry"); } TraceHr(ttidError, FAL, hr, FALSE, "ConvertToConFoldEntry"); return hr; }
HRESULT ConFoldPidl_v2::ConvertToConFoldEntry(OUT CConFoldEntry& ccfe) const { HRESULT hr = S_OK; Assert(this); if (!this) { return E_UNEXPECTED; } #if ( defined (MMMDBG) && defined ( _X86_ ) )
if ( (g_ccl.m_csMain.OwningThread == (HANDLE)GetCurrentThreadId()) && (g_ccl.m_csMain.LockCount != -1) ) { AssertSz(NULL, ".ConvertToConFoldEntry is called while the thread is owning g_ccl's Critical section. \r\n" "This may deadlock since .ConvertToConFoldEntry needs to marshall COM calls to other threads \r\n\r\n" "To Fix: Make a copy of ccfe from the pidl and Release the lock before calling .ConvertToConFoldEntry."); } #endif
// hr = ConvertToPidlInCache(*this, pcfp); // NOT REQUIRED. WE KNOW THIS IS A V2 PIDL!
// Initialize the data from the pidl
hr = ccfe.HrInitData(wizWizard, ncm, ncsm, ncs, &clsid, &guidId, dwCharacteristics, PbGetPersistBufPointer(), ulPersistBufSize, PszGetNamePointer(), PszGetDeviceNamePointer(), PszGetPhoneOrHostAddressPointer()); if (FAILED(hr)) { TraceHr(ttidShellFolder, FAL, hr, FALSE, "Failed in call to pcfe->HrInitData in ConvertToConFoldEntry"); } TraceHr(ttidError, FAL, hr, FALSE, "ConvertToConFoldEntry"); return hr; }
|