Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349/* * PROJECT: ReactOS Shell * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) * PURPOSE: CNetworkConnections Shell Folder items enumerator * COPYRIGHT: Copyright 2008 Johannes Anderwald (johannes.anderwald@reactos.org) */
#include "precomp.h"
PNETCONIDSTRUCT ILGetConnData(PCITEMID_CHILD pidl){ if (pidl && pidl->mkid.cb >= 2 + sizeof(NETCONIDSTRUCT)) { PNETCONIDSTRUCT pData = (PNETCONIDSTRUCT)pidl->mkid.abID; if (pData->Signature == NETCONIDSTRUCT_SIG) return pData; } return NULL;}
PWCHAR ILGetConnName(PCITEMID_CHILD pidl){ PNETCONIDSTRUCT pdata = ILGetConnData(pidl); if (!pdata) return NULL; return (PWCHAR)&pidl->mkid.abID[pdata->uNameOffset];}
PWCHAR ILGetDeviceName(PCITEMID_CHILD pidl){ PNETCONIDSTRUCT pdata = ILGetConnData(pidl); if (!pdata) return NULL; return (PWCHAR)&pidl->mkid.abID[pdata->uDeviceNameOffset];}
PITEMID_CHILD ILCreateNetConnectItem(INetConnection * pItem){ PITEMID_CHILD pidl; ULONG_PTR size; NETCON_PROPERTIES * pProperties; PNETCONIDSTRUCT pnetid; PWCHAR pwchName;
if (pItem->GetProperties(&pProperties) != S_OK) return NULL;
size = sizeof(WORD); /* nr of bytes in this item */ size += sizeof(NETCONIDSTRUCT); size += (wcslen(pProperties->pszwName) + 1) * sizeof(WCHAR); size += (wcslen(pProperties->pszwDeviceName) + 1) * sizeof(WCHAR);
/* Allocate enough memory for the trailing id which will indicate that this is a simple id */ pidl = static_cast<LPITEMIDLIST>(SHAlloc(size + sizeof(SHITEMID))); if (!pidl) goto end; pidl->mkid.cb = (WORD)size; ((PNETCONIDSTRUCT)(pidl->mkid.abID))->Signature = NETCONIDSTRUCT_SIG;
/* Copy the connection properties */ pnetid = ILGetConnData(pidl); memset(pnetid->Unknown, 0, sizeof(pnetid->Unknown)); pnetid->clsidThisObject = pProperties->clsidThisObject; pnetid->guidId = pProperties->guidId; pnetid->Status = pProperties->Status; pnetid->MediaType = pProperties->MediaType; pnetid->dwCharacter = pProperties->dwCharacter; pnetid->uNameOffset = sizeof(NETCONIDSTRUCT); pnetid->uDeviceNameOffset = ULONG(pnetid->uNameOffset + (wcslen(pProperties->pszwName) + 1) * sizeof(WCHAR));
pwchName = ILGetConnName(pidl); wcscpy(pwchName, pProperties->pszwName);
pwchName = ILGetDeviceName(pidl); wcscpy(pwchName, pProperties->pszwDeviceName);
/* Set the trailing id to null */ memset((void*)((ULONG_PTR)pidl + size), 0, sizeof(SHITEMID));end: NcFreeNetconProperties(pProperties);
return pidl;}
HRESULT ILGetConnection(PCITEMID_CHILD pidl, INetConnection ** pItem){ HRESULT hr; CComPtr<INetConnectionManager> pNetConMan; CComPtr<IEnumNetConnection> pEnumCon; CComPtr<INetConnection> INetCon; ULONG Count; NETCON_PROPERTIES * pProperties;
PNETCONIDSTRUCT pdata = ILGetConnData(pidl); if (!pdata) return E_FAIL;
/* get an instance to of IConnectionManager */ hr = CNetConnectionManager_CreateInstance(IID_PPV_ARG(INetConnectionManager, &pNetConMan)); if (FAILED_UNEXPECTEDLY(hr)) return hr;
hr = pNetConMan->EnumConnections(NCME_DEFAULT, &pEnumCon); if (FAILED_UNEXPECTEDLY(hr)) return hr;
while (TRUE) { hr = pEnumCon->Next(1, &INetCon, &Count); if (hr != S_OK) return E_FAIL;
hr = INetCon->GetProperties(&pProperties); if (FAILED_UNEXPECTEDLY(hr)) continue;
BOOL bSame = !memcmp(&pProperties->guidId, &pdata->guidId, sizeof(GUID));
NcFreeNetconProperties(pProperties);
if (bSame) { *pItem = INetCon.Detach(); return S_OK; } }
return E_FAIL;}
typedef struct tagENUMLIST{ struct tagENUMLIST *pNext; PITEMID_CHILD pidl;} ENUMLIST, *LPENUMLIST;
class CEnumIDList: public CComObjectRootEx<CComMultiThreadModelNoCS>, public IEnumIDList{ public: CEnumIDList(); ~CEnumIDList();
HRESULT Initialize();
// IEnumIDList STDMETHOD(Next)(ULONG celt, PITEMID_CHILD *rgelt, ULONG *pceltFetched) override; STDMETHOD(Skip)(ULONG celt) override; STDMETHOD(Reset)() override; STDMETHOD(Clone)(IEnumIDList **ppenum) override;
private: BOOL AddToEnumList(PITEMID_CHILD pidl);
LPENUMLIST m_pFirst; LPENUMLIST m_pLast; LPENUMLIST m_pCurrent;
public: DECLARE_NOT_AGGREGATABLE(CEnumIDList) DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CEnumIDList) COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList) END_COM_MAP()};
/************************************************************************** * AddToEnumList() */BOOLCEnumIDList::AddToEnumList(PITEMID_CHILD pidl){ LPENUMLIST pNew;
if (!pidl) return FALSE;
pNew = static_cast<LPENUMLIST>(SHAlloc(sizeof(ENUMLIST))); if (pNew) { pNew->pNext = NULL; pNew->pidl = pidl;
if (!m_pFirst) { m_pFirst = pNew; m_pCurrent = pNew; }
if (m_pLast) { /*add the new item to the end of the list */ m_pLast->pNext = pNew; }
/*update the last item pointer */ m_pLast = pNew; return TRUE; } return FALSE;}
CEnumIDList::CEnumIDList() : m_pFirst(NULL), m_pLast(NULL), m_pCurrent(NULL){}
CEnumIDList::~CEnumIDList(){ LPENUMLIST pDelete;
while (m_pFirst) { pDelete = m_pFirst; m_pFirst = pDelete->pNext; SHFree(pDelete->pidl); SHFree(pDelete); }}
HRESULTCEnumIDList::Initialize(){ HRESULT hr; CComPtr<INetConnectionManager> pNetConMan; CComPtr<IEnumNetConnection> pEnumCon; ULONG Count; PITEMID_CHILD pidl;
/* get an instance to of IConnectionManager */ hr = CNetConnectionManager_CreateInstance(IID_PPV_ARG(INetConnectionManager, &pNetConMan)); if (FAILED_UNEXPECTEDLY(hr)) return S_OK;
hr = pNetConMan->EnumConnections(NCME_DEFAULT, &pEnumCon); if (FAILED_UNEXPECTEDLY(hr)) return S_OK;
while (TRUE) { CComPtr<INetConnection> INetCon;
hr = pEnumCon->Next(1, &INetCon, &Count); if (hr != S_OK) break;
pidl = ILCreateNetConnectItem(INetCon); if (pidl) { AddToEnumList(pidl); } }
return S_OK;}
HRESULTWINAPICEnumIDList::Next( ULONG celt, PITEMID_CHILD *rgelt, ULONG *pceltFetched){ ULONG i; HRESULT hr = S_OK; PITEMID_CHILD temp;
if (pceltFetched) *pceltFetched = 0;
if (celt > 1 && !pceltFetched) { return E_INVALIDARG; }
if (celt > 0 && !m_pCurrent) { return S_FALSE; }
for (i = 0; i < celt; i++) { if (!m_pCurrent) { hr = S_FALSE; break; }
temp = ILClone(m_pCurrent->pidl); if (!temp) { hr = i ? S_FALSE : E_OUTOFMEMORY; break; } rgelt[i] = temp; m_pCurrent = m_pCurrent->pNext; }
if (pceltFetched) *pceltFetched = i;
return hr;}
HRESULTWINAPICEnumIDList::Skip(ULONG celt){ DWORD dwIndex; HRESULT hr = S_OK;
for (dwIndex = 0; dwIndex < celt; dwIndex++) { if (!m_pCurrent) { hr = S_FALSE; break; } m_pCurrent = m_pCurrent->pNext; }
return hr;}
HRESULTWINAPICEnumIDList::Reset(){ m_pCurrent = m_pFirst; return S_OK;}
HRESULTWINAPICEnumIDList::Clone( LPENUMIDLIST * ppenum){ return E_NOTIMPL;}
HRESULT CEnumIDList_CreateInstance(HWND hwndOwner, DWORD dwFlags, REFIID riid, LPVOID * ppv){ return ShellObjectCreatorInit<CEnumIDList>(riid, ppv);}