2 * Virtual Admin Tools Folder
4 * Copyright 2008 Johannes Anderwald
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 WINE_DEFAULT_DEBUG_CHANNEL (shell
);
27 * CSIDL_COMMON_ADMINTOOLS
28 * Note: CSIDL_ADMINTOOLS is ignored, tested with Window XP SP3+
31 /***********************************************************************
32 * AdminTools folder implementation
36 IShellFolder2Vtbl
*lpVtbl
;
37 IPersistFolder2Vtbl
*lpVtblPersistFolder2
;
43 LPITEMIDLIST pidlRoot
; /* absolute pidl */
46 int dwAttributes
; /* attributes returned by GetAttributesOf FIXME: use it */
49 static const shvheader AdminToolsSFHeader
[] = {
50 {IDS_SHV_COLUMN8
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 15},
51 {IDS_SHV_COLUMN2
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10},
52 {IDS_SHV_COLUMN3
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10},
53 {IDS_SHV_COLUMN4
, SHCOLSTATE_TYPE_DATE
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 12}
61 #define AdminToolsHELLVIEWCOLUMNS (4)
64 #define _IPersistFolder2_Offset ((INT_PTR)(&(((IGenericSFImpl*)0)->lpVtblPersistFolder2)))
65 #define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder2_Offset);
67 #define _IUnknown_(This) (IShellFolder*)&(This->lpVtbl)
68 #define _IShellFolder_(This) (IShellFolder*)&(This->lpVtbl)
70 #define _IPersist_(This) (IPersist*)&(This->lpVtblPersistFolder2)
71 #define _IPersistFolder_(This) (IPersistFolder*)&(This->lpVtblPersistFolder2)
72 #define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpVtblPersistFolder2)
74 /**************************************************************************
75 * ISF_AdminTools_fnQueryInterface
77 * NOTE does not support IPersist/IPersistFolder
79 static HRESULT WINAPI
ISF_AdminTools_fnQueryInterface(
80 IShellFolder2
* iface
, REFIID riid
, LPVOID
* ppvObj
)
82 IGenericSFImpl
*This
= (IGenericSFImpl
*)iface
;
84 TRACE ("(%p)->(%s,%p)\n", This
, shdebugstr_guid (riid
), ppvObj
);
88 if (IsEqualIID (riid
, &IID_IUnknown
) ||
89 IsEqualIID (riid
, &IID_IShellFolder
) ||
90 IsEqualIID (riid
, &IID_IShellFolder2
))
95 else if (IsEqualIID (riid
, &IID_IPersist
) ||
96 IsEqualIID (riid
, &IID_IPersistFolder
) ||
97 IsEqualIID (riid
, &IID_IPersistFolder2
))
99 *ppvObj
= _IPersistFolder2_ (This
);
104 IUnknown_AddRef ((IUnknown
*) (*ppvObj
));
105 TRACE ("-- Interface: (%p)->(%p)\n", ppvObj
, *ppvObj
);
108 TRACE ("-- Interface: E_NOINTERFACE\n");
109 return E_NOINTERFACE
;
112 static ULONG WINAPI
ISF_AdminTools_fnAddRef (IShellFolder2
* iface
)
114 IGenericSFImpl
*This
= (IGenericSFImpl
*)iface
;
115 ULONG refCount
= InterlockedIncrement(&This
->ref
);
117 TRACE ("(%p)->(count=%lu)\n", This
, refCount
- 1);
122 static ULONG WINAPI
ISF_AdminTools_fnRelease (IShellFolder2
* iface
)
124 IGenericSFImpl
*This
= (IGenericSFImpl
*)iface
;
125 ULONG refCount
= InterlockedDecrement(&This
->ref
);
127 TRACE ("(%p)->(count=%lu)\n", This
, refCount
+ 1);
131 TRACE ("-- destroying IShellFolder(%p)\n", This
);
133 SHFree (This
->pidlRoot
);
134 HeapFree(GetProcessHeap(), 0, This
->szTarget
);
135 HeapFree(GetProcessHeap(), 0, This
);
141 /**************************************************************************
142 * ISF_AdminTools_fnParseDisplayName
145 static HRESULT WINAPI
ISF_AdminTools_fnParseDisplayName (IShellFolder2
* iface
,
146 HWND hwndOwner
, LPBC pbc
, LPOLESTR lpszDisplayName
,
147 DWORD
* pchEaten
, LPITEMIDLIST
* ppidl
, DWORD
* pdwAttributes
)
149 IGenericSFImpl
*This
= (IGenericSFImpl
*)iface
;
151 TRACE("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
152 This
, hwndOwner
, pbc
, lpszDisplayName
, debugstr_w(lpszDisplayName
),
153 pchEaten
, ppidl
, pdwAttributes
);
159 MessageBoxW(NULL
, lpszDisplayName
, L
"ParseDisplayName", MB_OK
);
164 /**************************************************************************
165 * CreateAdminToolsEnumList()
167 static BOOL
CreateAdminToolsEnumList(IEnumIDList
*list
, IGenericSFImpl
*This
, DWORD dwFlags
)
169 TRACE("(%p)->(flags=0x%08x)\n", list
, dwFlags
);
170 /* enumerate the elements in %windir%\desktop */
171 return CreateFolderEnumList(list
, This
->szTarget
, dwFlags
);
174 /**************************************************************************
175 * ISF_AdminTools_fnEnumObjects
177 static HRESULT WINAPI
ISF_AdminTools_fnEnumObjects (IShellFolder2
* iface
,
178 HWND hwndOwner
, DWORD dwFlags
, LPENUMIDLIST
* ppEnumIDList
)
180 IGenericSFImpl
*This
= (IGenericSFImpl
*)iface
;
182 TRACE ("(%p)->(HWND=%p flags=0x%08lx pplist=%p)\n",
183 This
, hwndOwner
, dwFlags
, ppEnumIDList
);
185 if(!ppEnumIDList
) return E_OUTOFMEMORY
;
186 *ppEnumIDList
= IEnumIDList_Constructor();
188 CreateAdminToolsEnumList(*ppEnumIDList
, This
, dwFlags
);
190 TRACE ("-- (%p)->(new ID List: %p)\n", This
, *ppEnumIDList
);
192 return (*ppEnumIDList
) ? S_OK
: E_OUTOFMEMORY
;
195 /**************************************************************************
196 * ISF_AdminTools_fnBindToObject
198 static HRESULT WINAPI
ISF_AdminTools_fnBindToObject (IShellFolder2
* iface
,
199 LPCITEMIDLIST pidl
, LPBC pbcReserved
, REFIID riid
, LPVOID
* ppvOut
)
201 IGenericSFImpl
*This
= (IGenericSFImpl
*)iface
;
203 TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n", This
,
204 pidl
, pbcReserved
, shdebugstr_guid (riid
), ppvOut
);
206 return SHELL32_BindToChild (This
->pidlRoot
, NULL
, pidl
, riid
, ppvOut
);
209 /**************************************************************************
210 * ISF_AdminTools_fnBindToStorage
212 static HRESULT WINAPI
ISF_AdminTools_fnBindToStorage (IShellFolder2
* iface
,
213 LPCITEMIDLIST pidl
, LPBC pbcReserved
, REFIID riid
, LPVOID
* ppvOut
)
215 IGenericSFImpl
*This
= (IGenericSFImpl
*)iface
;
217 FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n",
218 This
, pidl
, pbcReserved
, shdebugstr_guid (riid
), ppvOut
);
224 /**************************************************************************
225 * ISF_AdminTools_fnCompareIDs
227 static HRESULT WINAPI
ISF_AdminTools_fnCompareIDs (IShellFolder2
* iface
,
228 LPARAM lParam
, LPCITEMIDLIST pidl1
, LPCITEMIDLIST pidl2
)
230 IGenericSFImpl
*This
= (IGenericSFImpl
*)iface
;
233 TRACE ("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", This
, lParam
, pidl1
, pidl2
);
234 nReturn
= SHELL32_CompareIDs (_IShellFolder_ (This
), lParam
, pidl1
, pidl2
);
235 TRACE ("-- %i\n", nReturn
);
239 /**************************************************************************
240 * ISF_AdminTools_fnCreateViewObject
242 static HRESULT WINAPI
ISF_AdminTools_fnCreateViewObject (IShellFolder2
* iface
,
243 HWND hwndOwner
, REFIID riid
, LPVOID
* ppvOut
)
246 LPSHELLVIEW pShellView
;
247 HRESULT hr
= E_INVALIDARG
;
248 IGenericSFImpl
*This
= (IGenericSFImpl
*)iface
;
250 TRACE ("(%p)->(hwnd=%p,%s,%p)\n", This
,
251 hwndOwner
, shdebugstr_guid (riid
), ppvOut
);
258 if (IsEqualIID (riid
, &IID_IDropTarget
))
260 WARN ("IDropTarget not implemented\n");
263 else if (IsEqualIID (riid
, &IID_IShellView
))
265 pShellView
= IShellView_Constructor ((IShellFolder
*) iface
);
268 hr
= IShellView_QueryInterface (pShellView
, riid
, ppvOut
);
269 IShellView_Release (pShellView
);
272 TRACE ("-- (%p)->(interface=%p)\n", This
, ppvOut
);
276 /**************************************************************************
277 * ISF_AdminTools_fnGetAttributesOf
279 static HRESULT WINAPI
ISF_AdminTools_fnGetAttributesOf (IShellFolder2
* iface
,
280 UINT cidl
, LPCITEMIDLIST
* apidl
, DWORD
* rgfInOut
)
282 IGenericSFImpl
*This
= (IGenericSFImpl
*)iface
;
284 static const DWORD dwAdminToolsAttributes
=
285 SFGAO_STORAGE
| SFGAO_HASPROPSHEET
| SFGAO_STORAGEANCESTOR
|
286 SFGAO_FILESYSANCESTOR
| SFGAO_FOLDER
| SFGAO_FILESYSTEM
;
288 TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
289 This
, cidl
, apidl
, rgfInOut
, rgfInOut
? *rgfInOut
: 0);
300 *rgfInOut
&= dwAdminToolsAttributes
;
302 while (cidl
> 0 && *apidl
) {
304 if (_ILIsAdminTools(*apidl
)) {
305 *rgfInOut
&= dwAdminToolsAttributes
;
307 SHELL32_GetItemAttributes (_IShellFolder_ (This
), *apidl
, rgfInOut
);
313 /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
314 *rgfInOut
&= ~SFGAO_VALIDATE
;
316 TRACE ("-- result=0x%08x\n", *rgfInOut
);
321 /**************************************************************************
322 * ISF_AdminTools_fnGetUIObjectOf
325 * HWND hwndOwner, //[in ] Parent window for any output
326 * UINT cidl, //[in ] array size
327 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
328 * REFIID riid, //[in ] Requested Interface
329 * UINT* prgfInOut, //[ ] reserved
330 * LPVOID* ppvObject) //[out] Resulting Interface
333 static HRESULT WINAPI
ISF_AdminTools_fnGetUIObjectOf (IShellFolder2
* iface
,
334 HWND hwndOwner
, UINT cidl
, LPCITEMIDLIST
* apidl
,
335 REFIID riid
, UINT
* prgfInOut
, LPVOID
* ppvOut
)
337 IGenericSFImpl
*This
= (IGenericSFImpl
*)iface
;
340 IUnknown
*pObj
= NULL
;
341 HRESULT hr
= E_INVALIDARG
;
343 TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
344 This
, hwndOwner
, cidl
, apidl
, shdebugstr_guid (riid
), prgfInOut
, ppvOut
);
351 if (IsEqualIID (riid
, &IID_IContextMenu
))
353 hr
= CDefFolderMenu_Create2(This
->pidlRoot
, hwndOwner
, cidl
, apidl
, (IShellFolder
*)iface
, NULL
, 0, NULL
, (IContextMenu
**)&pObj
);
355 else if (IsEqualIID (riid
, &IID_IDataObject
) && (cidl
>= 1))
357 pObj
= (LPUNKNOWN
) IDataObject_Constructor( hwndOwner
,
358 This
->pidlRoot
, apidl
, cidl
);
361 else if (IsEqualIID (riid
, &IID_IExtractIconA
) && (cidl
== 1))
363 pidl
= ILCombine (This
->pidlRoot
, apidl
[0]);
364 pObj
= (LPUNKNOWN
) IExtractIconA_Constructor (pidl
);
368 else if (IsEqualIID (riid
, &IID_IExtractIconW
) && (cidl
== 1))
370 pidl
= ILCombine (This
->pidlRoot
, apidl
[0]);
371 pObj
= (LPUNKNOWN
) IExtractIconW_Constructor (pidl
);
375 else if (IsEqualIID (riid
, &IID_IDropTarget
) && (cidl
>= 1))
377 hr
= IShellFolder_QueryInterface (iface
,
378 &IID_IDropTarget
, (LPVOID
*) & pObj
);
380 else if ((IsEqualIID(riid
,&IID_IShellLinkW
) ||
381 IsEqualIID(riid
,&IID_IShellLinkA
)) && (cidl
== 1))
383 pidl
= ILCombine (This
->pidlRoot
, apidl
[0]);
384 hr
= IShellLink_ConstructFromFile(NULL
, riid
, pidl
, (LPVOID
*)&pObj
);
390 if (SUCCEEDED(hr
) && !pObj
)
394 TRACE ("(%p)->hr=0x%08x\n", This
, hr
);
398 /**************************************************************************
399 * ISF_AdminTools_fnGetDisplayNameOf
402 static HRESULT WINAPI
ISF_AdminTools_fnGetDisplayNameOf (IShellFolder2
* iface
,
403 LPCITEMIDLIST pidl
, DWORD dwFlags
, LPSTRRET strRet
)
405 IGenericSFImpl
*This
= (IGenericSFImpl
*)iface
;
407 LPWSTR pszPath
, pOffset
;
410 TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", This
, pidl
, dwFlags
, strRet
);
416 pszPath
= CoTaskMemAlloc((MAX_PATH
+1) * sizeof(WCHAR
));
418 return E_OUTOFMEMORY
;
420 ZeroMemory(pszPath
, (MAX_PATH
+1) * sizeof(WCHAR
));
422 if (_ILIsAdminTools (pidl
))
424 if ((GET_SHGDN_RELATION (dwFlags
) == SHGDN_NORMAL
) &&
425 (GET_SHGDN_FOR (dwFlags
) & SHGDN_FORPARSING
))
426 wcscpy(pszPath
, This
->szTarget
);
427 else if (!HCR_GetClassNameW(&CLSID_AdminFolderShortcut
, pszPath
, MAX_PATH
))
430 else if (_ILIsPidlSimple(pidl
))
432 if ((GET_SHGDN_FOR(dwFlags
) & SHGDN_FORPARSING
) &&
433 (GET_SHGDN_RELATION(dwFlags
) != SHGDN_INFOLDER
) &&
436 wcscpy(pszPath
, This
->szTarget
);
437 pOffset
= PathAddBackslashW(pszPath
);
440 if (!_ILSimpleGetTextW(pidl
, pOffset
, MAX_PATH
+ 1 - (pOffset
- pszPath
)))
448 if (_ILSimpleGetTextW(pidl
, pszPath
, MAX_PATH
+ 1))
450 if (SHELL_FS_HideExtension(pszPath
))
451 PathRemoveExtensionW(pszPath
);
457 else if (_ILIsSpecialFolder(pidl
))
459 BOOL bSimplePidl
= _ILIsPidlSimple(pidl
);
463 if (!_ILSimpleGetTextW(pidl
, pszPath
, MAX_PATH
))
466 else if ((dwFlags
& SHGDN_FORPARSING
) && !bSimplePidl
)
470 wcscpy(pszPath
, This
->szTarget
);
471 PathAddBackslashW(pszPath
);
472 len
= wcslen(pszPath
);
474 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface
, pidl
, dwFlags
| SHGDN_INFOLDER
, pszPath
+ len
, MAX_PATH
+ 1 - len
)))
476 CoTaskMemFree(pszPath
);
477 return E_OUTOFMEMORY
;
485 strRet
->uType
= STRRET_WSTR
;
486 strRet
->u
.pOleStr
= pszPath
;
487 TRACE ("-- (%p)->(%s,0x%08x)\n", This
, debugstr_w(strRet
->u
.pOleStr
), hr
);
490 CoTaskMemFree(pszPath
);
495 /**************************************************************************
496 * ISF_AdminTools_fnSetNameOf
497 * Changes the name of a file object or subfolder, possibly changing its item
498 * identifier in the process.
501 * HWND hwndOwner, //[in ] Owner window for output
502 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
503 * LPCOLESTR lpszName, //[in ] the items new display name
504 * DWORD dwFlags, //[in ] SHGNO formatting flags
505 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
507 static HRESULT WINAPI
ISF_AdminTools_fnSetNameOf (IShellFolder2
* iface
,
508 HWND hwndOwner
, LPCITEMIDLIST pidl
, /* simple pidl */
509 LPCOLESTR lpName
, DWORD dwFlags
, LPITEMIDLIST
* pPidlOut
)
511 IGenericSFImpl
*This
= (IGenericSFImpl
*)iface
;
513 FIXME ("(%p)->(%p,pidl=%p,%s,%lu,%p)\n", This
, hwndOwner
, pidl
,
514 debugstr_w (lpName
), dwFlags
, pPidlOut
);
519 static HRESULT WINAPI
ISF_AdminTools_fnGetDefaultSearchGUID(IShellFolder2
*iface
,
522 IGenericSFImpl
*This
= (IGenericSFImpl
*)iface
;
524 FIXME ("(%p)\n", This
);
528 static HRESULT WINAPI
ISF_AdminTools_fnEnumSearches (IShellFolder2
*iface
,
529 IEnumExtraSearch
** ppenum
)
531 IGenericSFImpl
*This
= (IGenericSFImpl
*)iface
;
532 FIXME ("(%p)\n", This
);
536 static HRESULT WINAPI
ISF_AdminTools_fnGetDefaultColumn (IShellFolder2
* iface
,
537 DWORD dwRes
, ULONG
* pSort
, ULONG
* pDisplay
)
546 static HRESULT WINAPI
ISF_AdminTools_fnGetDefaultColumnState (
547 IShellFolder2
* iface
, UINT iColumn
, DWORD
* pcsFlags
)
549 if (!pcsFlags
|| iColumn
>= AdminToolsHELLVIEWCOLUMNS
)
551 *pcsFlags
= AdminToolsSFHeader
[iColumn
].pcsFlags
;
556 static HRESULT WINAPI
ISF_AdminTools_fnGetDetailsEx (IShellFolder2
* iface
,
557 LPCITEMIDLIST pidl
, const SHCOLUMNID
* pscid
, VARIANT
* pv
)
559 IGenericSFImpl
*This
= (IGenericSFImpl
*)iface
;
560 FIXME ("(%p): stub\n", This
);
565 static HRESULT WINAPI
ISF_AdminTools_fnGetDetailsOf (IShellFolder2
* iface
,
566 LPCITEMIDLIST pidl
, UINT iColumn
, SHELLDETAILS
* psd
)
568 IGenericSFImpl
*This
= (IGenericSFImpl
*)iface
;
569 WCHAR buffer
[MAX_PATH
] = {0};
572 TRACE("(%p)->(%p %i %p): stub\n", This
, pidl
, iColumn
, psd
);
574 if (iColumn
>= AdminToolsHELLVIEWCOLUMNS
)
577 psd
->fmt
= AdminToolsSFHeader
[iColumn
].fmt
;
578 psd
->cxChar
= AdminToolsSFHeader
[iColumn
].cxChar
;
581 psd
->str
.uType
= STRRET_WSTR
;
582 if (LoadStringW(shell32_hInstance
, AdminToolsSFHeader
[iColumn
].colnameid
, buffer
, MAX_PATH
))
583 hr
= SHStrDupW(buffer
, &psd
->str
.u
.pOleStr
);
588 psd
->str
.uType
= STRRET_CSTR
;
592 psd
->str
.uType
= STRRET_WSTR
;
593 hr
= IShellFolder_GetDisplayNameOf(iface
, pidl
,
594 SHGDN_NORMAL
| SHGDN_INFOLDER
, &psd
->str
);
597 _ILGetFileSize (pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
600 _ILGetFileType (pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
603 _ILGetFileDate (pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
610 static HRESULT WINAPI
ISF_AdminTools_fnMapColumnToSCID (
611 IShellFolder2
* iface
, UINT column
, SHCOLUMNID
* pscid
)
613 IGenericSFImpl
*This
= (IGenericSFImpl
*)iface
;
614 FIXME ("(%p): stub\n", This
);
618 static IShellFolder2Vtbl vt_ShellFolder2
=
620 ISF_AdminTools_fnQueryInterface
,
621 ISF_AdminTools_fnAddRef
,
622 ISF_AdminTools_fnRelease
,
623 ISF_AdminTools_fnParseDisplayName
,
624 ISF_AdminTools_fnEnumObjects
,
625 ISF_AdminTools_fnBindToObject
,
626 ISF_AdminTools_fnBindToStorage
,
627 ISF_AdminTools_fnCompareIDs
,
628 ISF_AdminTools_fnCreateViewObject
,
629 ISF_AdminTools_fnGetAttributesOf
,
630 ISF_AdminTools_fnGetUIObjectOf
,
631 ISF_AdminTools_fnGetDisplayNameOf
,
632 ISF_AdminTools_fnSetNameOf
,
634 ISF_AdminTools_fnGetDefaultSearchGUID
,
635 ISF_AdminTools_fnEnumSearches
,
636 ISF_AdminTools_fnGetDefaultColumn
,
637 ISF_AdminTools_fnGetDefaultColumnState
,
638 ISF_AdminTools_fnGetDetailsEx
,
639 ISF_AdminTools_fnGetDetailsOf
,
640 ISF_AdminTools_fnMapColumnToSCID
643 /************************************************************************
644 * IPF_AdminTools_QueryInterface
646 static HRESULT WINAPI
IPF_AdminTools_QueryInterface (
647 IPersistFolder2
* iface
, REFIID iid
, LPVOID
* ppvObj
)
649 _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl
, iface
);
651 TRACE ("(%p)\n", This
);
653 return IUnknown_QueryInterface (_IUnknown_ (This
), iid
, ppvObj
);
656 /************************************************************************
657 * IPF_AdminTools_AddRef
659 static ULONG WINAPI
IPF_AdminTools_AddRef (IPersistFolder2
* iface
)
661 _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl
, iface
);
663 TRACE ("(%p)->(count=%lu)\n", This
, This
->ref
);
665 return IUnknown_AddRef (_IUnknown_ (This
));
668 /************************************************************************
669 * IPF_AdminTools_Release
671 static ULONG WINAPI
IPF_AdminTools_Release (IPersistFolder2
* iface
)
673 _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl
, iface
);
675 TRACE ("(%p)->(count=%lu)\n", This
, This
->ref
);
677 return IUnknown_Release (_IUnknown_ (This
));
680 /************************************************************************
681 * IPF_AdminTools_GetClassID
683 static HRESULT WINAPI
IPF_AdminTools_GetClassID (
684 IPersistFolder2
* iface
, CLSID
* lpClassId
)
686 _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl
, iface
);
688 TRACE ("(%p)\n", This
);
690 memcpy(lpClassId
, &CLSID_AdminFolderShortcut
, sizeof(CLSID
));
695 /************************************************************************
696 * IPF_AdminTools_Initialize
699 static HRESULT WINAPI
IPF_AdminTools_Initialize (
700 IPersistFolder2
* iface
, LPCITEMIDLIST pidl
)
702 _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl
, iface
);
704 SHFree((LPVOID
)This
->pidlRoot
);
706 This
->pidlRoot
= ILClone(pidl
);
710 /**************************************************************************
711 * IPF_AdminTools_fnGetCurFolder
713 static HRESULT WINAPI
IPF_AdminTools_GetCurFolder (
714 IPersistFolder2
* iface
, LPITEMIDLIST
* pidl
)
716 _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl
, iface
);
718 TRACE ("(%p)->(%p)\n", This
, pidl
);
720 *pidl
= ILClone (This
->pidlRoot
);
724 static IPersistFolder2Vtbl vt_PersistFolder2
=
726 IPF_AdminTools_QueryInterface
,
727 IPF_AdminTools_AddRef
,
728 IPF_AdminTools_Release
,
729 IPF_AdminTools_GetClassID
,
730 IPF_AdminTools_Initialize
,
731 IPF_AdminTools_GetCurFolder
734 /**************************************************************************
735 * ISF_AdminTools_Constructor
737 HRESULT WINAPI
ISF_AdminTools_Constructor (
738 IUnknown
* pUnkOuter
, REFIID riid
, LPVOID
* ppv
)
743 TRACE ("unkOut=%p %s\n", pUnkOuter
, shdebugstr_guid (riid
));
746 return CLASS_E_NOAGGREGATION
;
748 sf
= HeapAlloc( GetProcessHeap(), 0, sizeof(*sf
) );
750 return E_OUTOFMEMORY
;
752 sf
->szTarget
= HeapAlloc( GetProcessHeap(), 0, MAX_PATH
* sizeof(WCHAR
) );
755 HeapFree(GetProcessHeap(), 0, sf
);
756 return E_OUTOFMEMORY
;
758 if (!SHGetSpecialFolderPathW(NULL
, sf
->szTarget
, CSIDL_COMMON_ADMINTOOLS
, FALSE
))
760 HeapFree(GetProcessHeap(), 0, sf
->szTarget
);
761 HeapFree(GetProcessHeap(), 0, sf
);
766 sf
->lpVtbl
= &vt_ShellFolder2
;
767 sf
->lpVtblPersistFolder2
= &vt_PersistFolder2
;
768 sf
->pidlRoot
= _ILCreateAdminTools(); /* my qualified pidl */
770 hr
= IUnknown_QueryInterface( _IUnknown_(sf
), riid
, ppv
);
771 IUnknown_Release( _IUnknown_(sf
) );
773 TRACE ("--(%p)\n", *ppv
);