[ADVAPI32] SEH-protext the calls to service control handlers
[reactos.git] / dll / shellext / netshell / enumlist.cpp
1 #include "precomp.h"
2
3 /**************************************************************************
4 * AddToEnumList()
5 */
6 BOOL
7 CEnumIDList::AddToEnumList(PITEMID_CHILD pidl)
8 {
9 LPENUMLIST pNew;
10
11 if (!pidl)
12 return FALSE;
13
14 pNew = static_cast<LPENUMLIST>(SHAlloc(sizeof(ENUMLIST)));
15 if (pNew)
16 {
17 pNew->pNext = NULL;
18 pNew->pidl = pidl;
19
20 if (!m_pFirst)
21 {
22 m_pFirst = pNew;
23 m_pCurrent = pNew;
24 }
25
26 if (m_pLast)
27 {
28 /*add the new item to the end of the list */
29 m_pLast->pNext = pNew;
30 }
31
32 /*update the last item pointer */
33 m_pLast = pNew;
34 return TRUE;
35 }
36 return FALSE;
37 }
38
39 CEnumIDList::CEnumIDList() :
40 m_ref(0),
41 m_pFirst(NULL),
42 m_pLast(NULL),
43 m_pCurrent(NULL)
44 {
45 }
46
47 CEnumIDList::~CEnumIDList()
48 {
49 LPENUMLIST pDelete;
50
51 while (m_pFirst)
52 {
53 pDelete = m_pFirst;
54 m_pFirst = pDelete->pNext;
55 SHFree(pDelete->pidl);
56 SHFree(pDelete);
57 }
58 }
59
60 HRESULT
61 WINAPI
62 CEnumIDList::QueryInterface(
63 REFIID riid,
64 LPVOID *ppvObj)
65 {
66 *ppvObj = NULL;
67
68 if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IEnumIDList))
69 {
70 *ppvObj = static_cast<IEnumIDList*>(this);
71 AddRef();
72 return S_OK;
73 }
74
75 return E_NOINTERFACE;
76 }
77
78 ULONG
79 WINAPI
80 CEnumIDList::AddRef()
81 {
82 ULONG refCount = InterlockedIncrement(&m_ref);
83
84 return refCount;
85 }
86
87 ULONG
88 WINAPI CEnumIDList::Release()
89 {
90 ULONG refCount = InterlockedDecrement(&m_ref);
91
92 if (!refCount)
93 delete this;
94
95 return refCount;
96 }
97
98 HRESULT
99 WINAPI
100 CEnumIDList::Next(
101 ULONG celt,
102 PITEMID_CHILD *rgelt,
103 ULONG *pceltFetched)
104 {
105 ULONG i;
106 HRESULT hr = S_OK;
107 PITEMID_CHILD temp;
108
109 if (pceltFetched)
110 *pceltFetched = 0;
111
112 if (celt > 1 && !pceltFetched)
113 {
114 return E_INVALIDARG;
115 }
116
117 if (celt > 0 && !m_pCurrent)
118 {
119 return S_FALSE;
120 }
121
122 for (i = 0; i < celt; i++)
123 {
124 if (!m_pCurrent)
125 break;
126
127 temp = ILClone(m_pCurrent->pidl);
128 rgelt[i] = temp;
129 m_pCurrent = m_pCurrent->pNext;
130 }
131
132 if (pceltFetched)
133 *pceltFetched = i;
134
135 return hr;
136 }
137
138 HRESULT
139 WINAPI
140 CEnumIDList::Skip(ULONG celt)
141 {
142 DWORD dwIndex;
143 HRESULT hr = S_OK;
144
145 for (dwIndex = 0; dwIndex < celt; dwIndex++)
146 {
147 if (!m_pCurrent)
148 {
149 hr = S_FALSE;
150 break;
151 }
152 m_pCurrent = m_pCurrent->pNext;
153 }
154
155 return hr;
156 }
157
158 HRESULT
159 WINAPI
160 CEnumIDList::Reset()
161 {
162 m_pCurrent = m_pFirst;
163 return S_OK;
164 }
165
166 HRESULT
167 WINAPI
168 CEnumIDList::Clone(
169 LPENUMIDLIST * ppenum)
170 {
171 return E_NOTIMPL;
172 }
173
174 LPPIDLDATA _ILGetDataPointer(LPITEMIDLIST pidl)
175 {
176 if (pidl && pidl->mkid.cb != 0x00)
177 return reinterpret_cast<LPPIDLDATA>(&pidl->mkid.abID);
178 return NULL;
179 }
180
181 LPITEMIDLIST _ILAlloc(BYTE type, unsigned int size)
182 {
183 LPITEMIDLIST pidlOut = NULL;
184
185 pidlOut = static_cast<LPITEMIDLIST>(SHAlloc(size + 5));
186 if (pidlOut)
187 {
188 LPPIDLDATA pData;
189
190 ZeroMemory(pidlOut, size + 5);
191 pidlOut->mkid.cb = size + 3;
192 pData = _ILGetDataPointer(pidlOut);
193 if (pData)
194 pData->type = type;
195
196 }
197
198 return pidlOut;
199 }
200
201 PITEMID_CHILD _ILCreateNetConnect()
202 {
203 PITEMID_CHILD pidlOut;
204
205 pidlOut = _ILAlloc(PT_GUID, sizeof(PIDLDATA));
206 if (pidlOut)
207 {
208 LPPIDLDATA pData = _ILGetDataPointer(pidlOut);
209
210 memcpy(&(pData->u.guid.guid), &CLSID_ConnectionFolder, sizeof(GUID));
211 }
212 return pidlOut;
213 }
214
215 GUID* _ILGetGUIDPointer(LPITEMIDLIST pidl)
216 {
217 LPPIDLDATA pdata = _ILGetDataPointer(pidl);
218
219 if (!pdata)
220 return NULL;
221
222 if (pdata->type != PT_GUID)
223 return NULL;
224 else
225 return &(pdata->u.guid.guid);
226
227 }
228
229 BOOL _ILIsNetConnect(LPCITEMIDLIST pidl)
230 {
231 const IID *piid = _ILGetGUIDPointer(const_cast<LPITEMIDLIST>(pidl));
232
233 if (piid)
234 return IsEqualIID(*piid, CLSID_ConnectionFolder);
235
236 return FALSE;
237 }
238
239 PITEMID_CHILD ILCreateNetConnectItem(INetConnection * pItem)
240 {
241 PITEMID_CHILD pidl;
242 LPPIDLDATA pdata;
243
244 pidl = _ILAlloc(0x99, sizeof(PIDLDATA));
245 pdata = _ILGetDataPointer(pidl);
246 pdata->u.value.pItem = pItem;
247
248 return pidl;
249 }
250
251 const VALUEStruct * _ILGetValueStruct(LPCITEMIDLIST pidl)
252 {
253 LPPIDLDATA pdata = _ILGetDataPointer(const_cast<LPITEMIDLIST>(pidl));
254
255 if (pdata && pdata->type==0x99)
256 return reinterpret_cast<const VALUEStruct*>(&pdata->u.value);
257
258 return NULL;
259 }