msi: Fix the registry root indices for Installer::RegistryValue.
[wine] / dlls / shell32 / shfldr_netplaces.c
1 /*
2  *      Network Places (Neighbourhood) folder
3  *
4  *      Copyright 1997                  Marcus Meissner
5  *      Copyright 1998, 1999, 2002      Juergen Schmied
6  *      Copyright 2003                  Mike McCormack for CodeWeavers
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22
23 #include "config.h"
24 #include "wine/port.h"
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <stdarg.h>
29 #include <stdio.h>
30
31 #define COBJMACROS
32 #define NONAMELESSUNION
33 #define NONAMELESSSTRUCT
34
35 #include "winerror.h"
36 #include "windef.h"
37 #include "winbase.h"
38 #include "winreg.h"
39
40 #include "pidl.h"
41 #include "enumidlist.h"
42 #include "undocshell.h"
43 #include "shell32_main.h"
44 #include "shresdef.h"
45 #include "wine/debug.h"
46 #include "debughlp.h"
47 #include "shfldr.h"
48
49 WINE_DEFAULT_DEBUG_CHANNEL (shell);
50
51 /***********************************************************************
52 *   IShellFolder implementation
53 */
54
55 typedef struct {
56     const IShellFolder2Vtbl  *lpVtbl;
57     LONG                       ref;
58     const IPersistFolder2Vtbl *lpVtblPersistFolder2;
59
60     /* both paths are parsible from the desktop */
61     LPITEMIDLIST pidlRoot;      /* absolute pidl */
62 } IGenericSFImpl;
63
64 static const IShellFolder2Vtbl vt_ShellFolder2;
65 static const IPersistFolder2Vtbl vt_NP_PersistFolder2;
66
67
68 #define _IPersistFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpVtblPersistFolder2)))
69 #define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder2_Offset);
70
71 #define _IUnknown_(This)        (IUnknown*)&(This->lpVtbl)
72 #define _IShellFolder_(This)    (IShellFolder*)&(This->lpVtbl)
73 #define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpVtblPersistFolder2)
74
75 static shvheader NetworkPlacesSFHeader[] = {
76     {IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
77     {IDS_SHV_COLUMN9, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10}
78 };
79
80 #define NETWORKPLACESSHELLVIEWCOLUMNS 2
81
82 /**************************************************************************
83 *       ISF_NetworkPlaces_Constructor
84 */
85 HRESULT WINAPI ISF_NetworkPlaces_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
86 {
87     IGenericSFImpl *sf;
88
89     TRACE ("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid (riid));
90
91     if (!ppv)
92         return E_POINTER;
93     if (pUnkOuter)
94         return CLASS_E_NOAGGREGATION;
95
96     sf = (IGenericSFImpl *) HeapAlloc ( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (IGenericSFImpl));
97     if (!sf)
98         return E_OUTOFMEMORY;
99
100     sf->ref = 0;
101     sf->lpVtbl = &vt_ShellFolder2;
102     sf->lpVtblPersistFolder2 = &vt_NP_PersistFolder2;
103     sf->pidlRoot = _ILCreateNetHood();  /* my qualified pidl */
104
105     if (!SUCCEEDED (IUnknown_QueryInterface (_IUnknown_ (sf), riid, ppv)))
106     {
107         IUnknown_Release (_IUnknown_ (sf));
108         return E_NOINTERFACE;
109     }
110
111     TRACE ("--(%p)\n", sf);
112     return S_OK;
113 }
114
115 /**************************************************************************
116  *      ISF_NetworkPlaces_fnQueryInterface
117  *
118  * NOTE
119  *     supports not IPersist/IPersistFolder
120  */
121 static HRESULT WINAPI ISF_NetworkPlaces_fnQueryInterface (IShellFolder2 *iface, REFIID riid, LPVOID *ppvObj)
122 {
123     IGenericSFImpl *This = (IGenericSFImpl *)iface;
124
125     TRACE ("(%p)->(%s,%p)\n", This, shdebugstr_guid (riid), ppvObj);
126
127     *ppvObj = NULL;
128
129     if (IsEqualIID (riid, &IID_IUnknown) ||
130         IsEqualIID (riid, &IID_IShellFolder) ||
131         IsEqualIID (riid, &IID_IShellFolder2))
132     {
133         *ppvObj = This;
134     }
135     else if (IsEqualIID (riid, &IID_IPersist) ||
136              IsEqualIID (riid, &IID_IPersistFolder) ||
137              IsEqualIID (riid, &IID_IPersistFolder2))
138     {
139         *ppvObj = _IPersistFolder2_ (This);
140     }
141
142     if (*ppvObj)
143     {
144         IUnknown_AddRef ((IUnknown *) (*ppvObj));
145         TRACE ("-- Interface: (%p)->(%p)\n", ppvObj, *ppvObj);
146         return S_OK;
147     }
148     TRACE ("-- Interface: E_NOINTERFACE\n");
149     return E_NOINTERFACE;
150 }
151
152 static ULONG WINAPI ISF_NetworkPlaces_fnAddRef (IShellFolder2 * iface)
153 {
154     IGenericSFImpl *This = (IGenericSFImpl *)iface;
155     ULONG refCount = InterlockedIncrement(&This->ref);
156
157     TRACE ("(%p)->(count=%u)\n", This, refCount - 1);
158
159     return refCount;
160 }
161
162 static ULONG WINAPI ISF_NetworkPlaces_fnRelease (IShellFolder2 * iface)
163 {
164     IGenericSFImpl *This = (IGenericSFImpl *)iface;
165     ULONG refCount = InterlockedDecrement(&This->ref);
166
167     TRACE ("(%p)->(count=%u)\n", This, refCount + 1);
168
169     if (!refCount) {
170         TRACE ("-- destroying IShellFolder(%p)\n", This);
171         SHFree (This->pidlRoot);
172         HeapFree (GetProcessHeap(), 0, This);
173     }
174     return refCount;
175 }
176
177 /**************************************************************************
178 *       ISF_NetworkPlaces_fnParseDisplayName
179 */
180 static HRESULT WINAPI ISF_NetworkPlaces_fnParseDisplayName (IShellFolder2 * iface,
181                HWND hwndOwner, LPBC pbcReserved, LPOLESTR lpszDisplayName,
182                DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes)
183 {
184     IGenericSFImpl *This = (IGenericSFImpl *)iface;
185
186     HRESULT hr = E_UNEXPECTED;
187
188     TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n", This,
189             hwndOwner, pbcReserved, lpszDisplayName, debugstr_w (lpszDisplayName),
190             pchEaten, ppidl, pdwAttributes);
191
192     *ppidl = 0;
193     if (pchEaten)
194         *pchEaten = 0;          /* strange but like the original */
195
196     TRACE ("(%p)->(-- ret=0x%08x)\n", This, hr);
197
198     return hr;
199 }
200
201 /**************************************************************************
202 *               ISF_NetworkPlaces_fnEnumObjects
203 */
204 static HRESULT WINAPI ISF_NetworkPlaces_fnEnumObjects (IShellFolder2 * iface,
205                HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST * ppEnumIDList)
206 {
207     IGenericSFImpl *This = (IGenericSFImpl *)iface;
208
209     TRACE ("(%p)->(HWND=%p flags=0x%08x pplist=%p)\n", This,
210             hwndOwner, dwFlags, ppEnumIDList);
211
212     *ppEnumIDList = IEnumIDList_Constructor();
213
214     TRACE ("-- (%p)->(new ID List: %p)\n", This, *ppEnumIDList);
215
216     return (*ppEnumIDList) ? S_OK : E_OUTOFMEMORY;
217 }
218
219 /**************************************************************************
220 *               ISF_NetworkPlaces_fnBindToObject
221 */
222 static HRESULT WINAPI ISF_NetworkPlaces_fnBindToObject (IShellFolder2 * iface,
223                LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
224 {
225     IGenericSFImpl *This = (IGenericSFImpl *)iface;
226
227     TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n", This,
228             pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
229
230     return SHELL32_BindToChild (This->pidlRoot, NULL, pidl, riid, ppvOut);
231 }
232
233 /**************************************************************************
234 *       ISF_NetworkPlaces_fnBindToStorage
235 */
236 static HRESULT WINAPI ISF_NetworkPlaces_fnBindToStorage (IShellFolder2 * iface,
237                LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
238 {
239     IGenericSFImpl *This = (IGenericSFImpl *)iface;
240
241     FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n", This,
242             pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
243
244     *ppvOut = NULL;
245     return E_NOTIMPL;
246 }
247
248 /**************************************************************************
249 *       ISF_NetworkPlaces_fnCompareIDs
250 */
251
252 static HRESULT WINAPI ISF_NetworkPlaces_fnCompareIDs (IShellFolder2 * iface,
253                LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
254 {
255     IGenericSFImpl *This = (IGenericSFImpl *)iface;
256     int nReturn;
257
258     TRACE ("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", This, lParam, pidl1, pidl2);
259     nReturn = SHELL32_CompareIDs (_IShellFolder_ (This), lParam, pidl1, pidl2);
260     TRACE ("-- %i\n", nReturn);
261     return nReturn;
262 }
263
264 /**************************************************************************
265 *       ISF_NetworkPlaces_fnCreateViewObject
266 */
267 static HRESULT WINAPI ISF_NetworkPlaces_fnCreateViewObject (IShellFolder2 * iface,
268                HWND hwndOwner, REFIID riid, LPVOID * ppvOut)
269 {
270     IGenericSFImpl *This = (IGenericSFImpl *)iface;
271     LPSHELLVIEW pShellView;
272     HRESULT hr = E_INVALIDARG;
273
274     TRACE ("(%p)->(hwnd=%p,%s,%p)\n", This,
275            hwndOwner, shdebugstr_guid (riid), ppvOut);
276
277     if (!ppvOut)
278         return hr;
279
280     *ppvOut = NULL;
281
282     if (IsEqualIID (riid, &IID_IDropTarget))
283     {
284         WARN ("IDropTarget not implemented\n");
285         hr = E_NOTIMPL;
286     }
287     else if (IsEqualIID (riid, &IID_IContextMenu))
288     {
289         WARN ("IContextMenu not implemented\n");
290         hr = E_NOTIMPL;
291     }
292     else if (IsEqualIID (riid, &IID_IShellView))
293     {
294         pShellView = IShellView_Constructor ((IShellFolder *) iface);
295         if (pShellView)
296         {
297             hr = IShellView_QueryInterface (pShellView, riid, ppvOut);
298             IShellView_Release (pShellView);
299         }
300     }
301     TRACE ("-- (%p)->(interface=%p)\n", This, ppvOut);
302     return hr;
303 }
304
305 /**************************************************************************
306 *  ISF_NetworkPlaces_fnGetAttributesOf
307 */
308 static HRESULT WINAPI ISF_NetworkPlaces_fnGetAttributesOf (IShellFolder2 * iface,
309                UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut)
310 {
311     IGenericSFImpl *This = (IGenericSFImpl *)iface;
312     HRESULT hr = S_OK;
313
314     TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n", This,
315             cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
316
317     if (!rgfInOut)
318         return E_INVALIDARG;
319     if (cidl && !apidl)
320         return E_INVALIDARG;
321
322     if (*rgfInOut == 0)
323         *rgfInOut = ~0;
324
325     if (cidl == 0)
326     {
327         IShellFolder *psfParent = NULL;
328         LPCITEMIDLIST rpidl = NULL;
329
330         hr = SHBindToParent(This->pidlRoot, &IID_IShellFolder, (LPVOID*)&psfParent, (LPCITEMIDLIST*)&rpidl);
331         if(SUCCEEDED(hr))
332         {
333             SHELL32_GetItemAttributes (psfParent, rpidl, rgfInOut);
334             IShellFolder_Release(psfParent);
335         }
336     }
337     else
338     {
339         while (cidl > 0 && *apidl)
340         {
341             pdump (*apidl);
342             SHELL32_GetItemAttributes (_IShellFolder_ (This), *apidl, rgfInOut);
343             apidl++;
344             cidl--;
345         }
346     }
347
348     /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
349     *rgfInOut &= ~SFGAO_VALIDATE;
350
351     TRACE ("-- result=0x%08x\n", *rgfInOut);
352     return hr;
353 }
354
355 /**************************************************************************
356 *       ISF_NetworkPlaces_fnGetUIObjectOf
357 *
358 * PARAMETERS
359 *  hwndOwner [in]  Parent window for any output
360 *  cidl      [in]  array size
361 *  apidl     [in]  simple pidl array
362 *  riid      [in]  Requested Interface
363 *  prgfInOut [   ] reserved
364 *  ppvObject [out] Resulting Interface
365 *
366 */
367 static HRESULT WINAPI ISF_NetworkPlaces_fnGetUIObjectOf (IShellFolder2 * iface,
368                HWND hwndOwner, UINT cidl, LPCITEMIDLIST * apidl, REFIID riid,
369                UINT * prgfInOut, LPVOID * ppvOut)
370 {
371     IGenericSFImpl *This = (IGenericSFImpl *)iface;
372
373     LPITEMIDLIST pidl;
374     IUnknown *pObj = NULL;
375     HRESULT hr = E_INVALIDARG;
376
377     TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n", This,
378             hwndOwner, cidl, apidl, shdebugstr_guid (riid), prgfInOut, ppvOut);
379
380     if (!ppvOut)
381         return hr;
382
383     *ppvOut = NULL;
384
385     if (IsEqualIID (riid, &IID_IContextMenu) && (cidl >= 1))
386     {
387         pObj = (LPUNKNOWN) ISvItemCm_Constructor ((IShellFolder *) iface, This->pidlRoot, apidl, cidl);
388         hr = S_OK;
389     }
390     else if (IsEqualIID (riid, &IID_IDataObject) && (cidl >= 1))
391     {
392         pObj = (LPUNKNOWN) IDataObject_Constructor (hwndOwner, This->pidlRoot, apidl, cidl);
393         hr = S_OK;
394     }
395     else if (IsEqualIID (riid, &IID_IExtractIconA) && (cidl == 1))
396     {
397         pidl = ILCombine (This->pidlRoot, apidl[0]);
398         pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl);
399         SHFree (pidl);
400         hr = S_OK;
401     }
402     else if (IsEqualIID (riid, &IID_IExtractIconW) && (cidl == 1))
403     {
404         pidl = ILCombine (This->pidlRoot, apidl[0]);
405         pObj = (LPUNKNOWN) IExtractIconW_Constructor (pidl);
406         SHFree (pidl);
407         hr = S_OK;
408     }
409     else if (IsEqualIID (riid, &IID_IDropTarget) && (cidl >= 1))
410     {
411         hr = IShellFolder_QueryInterface (iface, &IID_IDropTarget, (LPVOID *) & pObj);
412     }
413     else
414         hr = E_NOINTERFACE;
415
416     if (SUCCEEDED(hr) && !pObj)
417         hr = E_OUTOFMEMORY;
418
419     *ppvOut = pObj;
420     TRACE ("(%p)->hr=0x%08x\n", This, hr);
421     return hr;
422 }
423
424 /**************************************************************************
425 *       ISF_NetworkPlaces_fnGetDisplayNameOf
426 *
427 */
428 static HRESULT WINAPI ISF_NetworkPlaces_fnGetDisplayNameOf (IShellFolder2 * iface,
429                LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
430 {
431     IGenericSFImpl *This = (IGenericSFImpl *)iface;
432
433     FIXME ("(%p)->(pidl=%p,0x%08x,%p)\n", This, pidl, dwFlags, strRet);
434     pdump (pidl);
435
436     if (!strRet)
437         return E_INVALIDARG;
438
439     return E_NOTIMPL;
440 }
441
442 /**************************************************************************
443 *  ISF_NetworkPlaces_fnSetNameOf
444 *  Changes the name of a file object or subfolder, possibly changing its item
445 *  identifier in the process.
446 *
447 * PARAMETERS
448 *  hwndOwner [in]  Owner window for output
449 *  pidl      [in]  simple pidl of item to change
450 *  lpszName  [in]  the items new display name
451 *  dwFlags   [in]  SHGNO formatting flags
452 *  ppidlOut  [out] simple pidl returned
453 */
454 static HRESULT WINAPI ISF_NetworkPlaces_fnSetNameOf (IShellFolder2 * iface,
455                HWND hwndOwner, LPCITEMIDLIST pidl,      /*simple pidl */
456                LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut)
457 {
458     IGenericSFImpl *This = (IGenericSFImpl *)iface;
459     FIXME ("(%p)->(%p,pidl=%p,%s,%u,%p)\n", This,
460             hwndOwner, pidl, debugstr_w (lpName), dwFlags, pPidlOut);
461     return E_FAIL;
462 }
463
464 static HRESULT WINAPI ISF_NetworkPlaces_fnGetDefaultSearchGUID (
465                IShellFolder2 * iface, GUID * pguid)
466 {
467     IGenericSFImpl *This = (IGenericSFImpl *)iface;
468     FIXME ("(%p)\n", This);
469     return E_NOTIMPL;
470 }
471
472 static HRESULT WINAPI ISF_NetworkPlaces_fnEnumSearches (IShellFolder2 * iface,
473                IEnumExtraSearch ** ppenum)
474 {
475     IGenericSFImpl *This = (IGenericSFImpl *)iface;
476     FIXME ("(%p)\n", This);
477     return E_NOTIMPL;
478 }
479
480 static HRESULT WINAPI ISF_NetworkPlaces_fnGetDefaultColumn (IShellFolder2 * iface,
481                DWORD dwRes, ULONG * pSort, ULONG * pDisplay)
482 {
483     IGenericSFImpl *This = (IGenericSFImpl *)iface;
484
485     TRACE ("(%p)\n", This);
486
487     if (pSort)
488         *pSort = 0;
489     if (pDisplay)
490         *pDisplay = 0;
491
492     return S_OK;
493 }
494
495 static HRESULT WINAPI ISF_NetworkPlaces_fnGetDefaultColumnState (
496                IShellFolder2 * iface, UINT iColumn, DWORD * pcsFlags)
497 {
498     IGenericSFImpl *This = (IGenericSFImpl *)iface;
499
500     TRACE ("(%p)\n", This);
501
502     if (!pcsFlags || iColumn >= NETWORKPLACESSHELLVIEWCOLUMNS)
503         return E_INVALIDARG;
504     *pcsFlags = NetworkPlacesSFHeader[iColumn].pcsFlags;
505     return S_OK;
506 }
507
508 static HRESULT WINAPI ISF_NetworkPlaces_fnGetDetailsEx (IShellFolder2 * iface,
509                LPCITEMIDLIST pidl, const SHCOLUMNID * pscid, VARIANT * pv)
510 {
511     IGenericSFImpl *This = (IGenericSFImpl *)iface;
512     FIXME ("(%p)\n", This);
513     return E_NOTIMPL;
514 }
515
516 static HRESULT WINAPI ISF_NetworkPlaces_fnGetDetailsOf (IShellFolder2 * iface,
517                LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS * psd)
518 {
519     IGenericSFImpl *This = (IGenericSFImpl *)iface;
520
521     FIXME ("(%p)->(%p %i %p)\n", This, pidl, iColumn, psd);
522
523     return E_NOTIMPL;
524 }
525
526 static HRESULT WINAPI ISF_NetworkPlaces_fnMapColumnToSCID (IShellFolder2 * iface,
527                UINT column, SHCOLUMNID * pscid)
528 {
529     IGenericSFImpl *This = (IGenericSFImpl *)iface;
530
531     FIXME ("(%p)\n", This);
532
533     return E_NOTIMPL;
534 }
535
536 static const IShellFolder2Vtbl vt_ShellFolder2 = {
537     ISF_NetworkPlaces_fnQueryInterface,
538     ISF_NetworkPlaces_fnAddRef,
539     ISF_NetworkPlaces_fnRelease,
540     ISF_NetworkPlaces_fnParseDisplayName,
541     ISF_NetworkPlaces_fnEnumObjects,
542     ISF_NetworkPlaces_fnBindToObject,
543     ISF_NetworkPlaces_fnBindToStorage,
544     ISF_NetworkPlaces_fnCompareIDs,
545     ISF_NetworkPlaces_fnCreateViewObject,
546     ISF_NetworkPlaces_fnGetAttributesOf,
547     ISF_NetworkPlaces_fnGetUIObjectOf,
548     ISF_NetworkPlaces_fnGetDisplayNameOf,
549     ISF_NetworkPlaces_fnSetNameOf,
550     /* ShellFolder2 */
551     ISF_NetworkPlaces_fnGetDefaultSearchGUID,
552     ISF_NetworkPlaces_fnEnumSearches,
553     ISF_NetworkPlaces_fnGetDefaultColumn,
554     ISF_NetworkPlaces_fnGetDefaultColumnState,
555     ISF_NetworkPlaces_fnGetDetailsEx,
556     ISF_NetworkPlaces_fnGetDetailsOf,
557     ISF_NetworkPlaces_fnMapColumnToSCID
558 };
559
560 /************************************************************************
561  *      INPFldr_PersistFolder2_QueryInterface
562  */
563 static HRESULT WINAPI INPFldr_PersistFolder2_QueryInterface (IPersistFolder2 * iface,
564                REFIID iid, LPVOID * ppvObj)
565 {
566     _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
567
568     TRACE ("(%p)\n", This);
569
570     return IUnknown_QueryInterface (_IUnknown_ (This), iid, ppvObj);
571 }
572
573 /************************************************************************
574  *      INPFldr_PersistFolder2_AddRef
575  */
576 static ULONG WINAPI INPFldr_PersistFolder2_AddRef (IPersistFolder2 * iface)
577 {
578     _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
579
580     TRACE ("(%p)->(count=%u)\n", This, This->ref);
581
582     return IUnknown_AddRef (_IUnknown_ (This));
583 }
584
585 /************************************************************************
586  *      ISFPersistFolder_Release
587  */
588 static ULONG WINAPI INPFldr_PersistFolder2_Release (IPersistFolder2 * iface)
589 {
590     _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
591
592     TRACE ("(%p)->(count=%u)\n", This, This->ref);
593
594     return IUnknown_Release (_IUnknown_ (This));
595 }
596
597 /************************************************************************
598  *      INPFldr_PersistFolder2_GetClassID
599  */
600 static HRESULT WINAPI INPFldr_PersistFolder2_GetClassID (
601                IPersistFolder2 * iface, CLSID * lpClassId)
602 {
603     _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
604
605     TRACE ("(%p)\n", This);
606
607     if (!lpClassId)
608         return E_POINTER;
609
610     *lpClassId = CLSID_NetworkPlaces;
611
612     return S_OK;
613 }
614
615 /************************************************************************
616  *      INPFldr_PersistFolder2_Initialize
617  *
618  * NOTES: it makes no sense to change the pidl
619  */
620 static HRESULT WINAPI INPFldr_PersistFolder2_Initialize (
621                IPersistFolder2 * iface, LPCITEMIDLIST pidl)
622 {
623     _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
624
625     TRACE ("(%p)->(%p)\n", This, pidl);
626
627     return E_NOTIMPL;
628 }
629
630 /**************************************************************************
631  *      IPersistFolder2_fnGetCurFolder
632  */
633 static HRESULT WINAPI INPFldr_PersistFolder2_GetCurFolder (
634                IPersistFolder2 * iface, LPITEMIDLIST * pidl)
635 {
636     _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
637
638     TRACE ("(%p)->(%p)\n", This, pidl);
639
640     if (!pidl)
641         return E_POINTER;
642
643     *pidl = ILClone (This->pidlRoot);
644
645     return S_OK;
646 }
647
648 static const IPersistFolder2Vtbl vt_NP_PersistFolder2 =
649 {
650     INPFldr_PersistFolder2_QueryInterface,
651     INPFldr_PersistFolder2_AddRef,
652     INPFldr_PersistFolder2_Release,
653     INPFldr_PersistFolder2_GetClassID,
654     INPFldr_PersistFolder2_Initialize,
655     INPFldr_PersistFolder2_GetCurFolder
656 };