winegstreamer: Set MF_SA_D3D11_AWARE attribute for h264 transform.
[wine.git] / dlls / shell32 / shfldr_mycomp.c
blob2f4ebd580c1cdd54cc73c74edd18d7030f38726f
1 /*
2 * Virtual Workplace folder
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998, 1999, 2002 Juergen Schmied
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdarg.h>
25 #include <stdio.h>
27 #define COBJMACROS
28 #define NONAMELESSUNION
30 #include "winerror.h"
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winreg.h"
35 #include "wingdi.h"
36 #include "pidl.h"
37 #include "shlguid.h"
38 #include "shell32_main.h"
39 #include "shresdef.h"
40 #include "shlwapi.h"
41 #include "wine/debug.h"
42 #include "debughlp.h"
43 #include "shfldr.h"
45 WINE_DEFAULT_DEBUG_CHANNEL (shell);
47 /***********************************************************************
48 * IShellFolder implementation
51 typedef struct {
52 IShellFolder2 IShellFolder2_iface;
53 IPersistFolder2 IPersistFolder2_iface;
54 LONG ref;
56 /* both paths are parsible from the desktop */
57 LPITEMIDLIST pidlRoot; /* absolute pidl */
58 } IMyComputerFolderImpl;
60 static const IShellFolder2Vtbl vt_ShellFolder2;
61 static const IPersistFolder2Vtbl vt_PersistFolder2;
63 static inline IMyComputerFolderImpl *impl_from_IShellFolder2(IShellFolder2 *iface)
65 return CONTAINING_RECORD(iface, IMyComputerFolderImpl, IShellFolder2_iface);
68 static inline IMyComputerFolderImpl *impl_from_IPersistFolder2(IPersistFolder2 *iface)
70 return CONTAINING_RECORD(iface, IMyComputerFolderImpl, IPersistFolder2_iface);
74 /***********************************************************************
75 * IShellFolder [MyComputer] implementation
78 static const shvheader mycomputer_header[] =
80 { &FMTID_Storage, PID_STG_NAME, IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
81 { &FMTID_Storage, PID_STG_STORAGETYPE, IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
82 { NULL, 0, IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
83 { NULL, 0, IDS_SHV_COLUMN7, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
86 /**************************************************************************
87 * ISF_MyComputer_Constructor
89 HRESULT WINAPI ISF_MyComputer_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
91 IMyComputerFolderImpl *sf;
93 TRACE ("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid (riid));
95 if (!ppv)
96 return E_POINTER;
97 if (pUnkOuter)
98 return CLASS_E_NOAGGREGATION;
100 sf = LocalAlloc (LMEM_ZEROINIT, sizeof (IMyComputerFolderImpl));
101 if (!sf)
102 return E_OUTOFMEMORY;
104 sf->ref = 0;
105 sf->IShellFolder2_iface.lpVtbl = &vt_ShellFolder2;
106 sf->IPersistFolder2_iface.lpVtbl = &vt_PersistFolder2;
107 sf->pidlRoot = _ILCreateMyComputer (); /* my qualified pidl */
109 if (FAILED (IShellFolder2_QueryInterface (&sf->IShellFolder2_iface, riid, ppv)))
111 IShellFolder2_Release (&sf->IShellFolder2_iface);
112 return E_NOINTERFACE;
115 TRACE ("--(%p)\n", sf);
116 return S_OK;
119 /**************************************************************************
120 * ISF_MyComputer_fnQueryInterface
122 * NOTES supports not IPersist/IPersistFolder
124 static HRESULT WINAPI ISF_MyComputer_fnQueryInterface (IShellFolder2 *iface,
125 REFIID riid, LPVOID *ppvObj)
127 IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
129 TRACE ("(%p)->(%s,%p)\n", This, shdebugstr_guid (riid), ppvObj);
131 *ppvObj = NULL;
133 if (IsEqualIID (riid, &IID_IUnknown) ||
134 IsEqualIID (riid, &IID_IShellFolder) ||
135 IsEqualIID (riid, &IID_IShellFolder2))
137 *ppvObj = &This->IShellFolder2_iface;
139 else if (IsEqualIID (riid, &IID_IPersist) ||
140 IsEqualIID (riid, &IID_IPersistFolder) ||
141 IsEqualIID (riid, &IID_IPersistFolder2))
143 *ppvObj = &This->IPersistFolder2_iface;
146 if (*ppvObj)
148 IUnknown_AddRef ((IUnknown *) (*ppvObj));
149 TRACE ("-- Interface: (%p)->(%p)\n", ppvObj, *ppvObj);
150 return S_OK;
152 TRACE ("-- Interface: E_NOINTERFACE\n");
153 return E_NOINTERFACE;
156 static ULONG WINAPI ISF_MyComputer_fnAddRef (IShellFolder2 * iface)
158 IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
159 ULONG refCount = InterlockedIncrement(&This->ref);
161 TRACE ("(%p)->(count=%lu)\n", This, refCount - 1);
163 return refCount;
166 static ULONG WINAPI ISF_MyComputer_fnRelease (IShellFolder2 * iface)
168 IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
169 ULONG refCount = InterlockedDecrement(&This->ref);
171 TRACE ("(%p)->(count=%lu)\n", This, refCount + 1);
173 if (!refCount)
175 TRACE ("-- destroying IShellFolder(%p)\n", This);
176 SHFree (This->pidlRoot);
177 LocalFree (This);
179 return refCount;
182 /**************************************************************************
183 * ISF_MyComputer_fnParseDisplayName
185 static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName (IShellFolder2 *iface,
186 HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName,
187 DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes)
189 IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
190 HRESULT hr = E_INVALIDARG;
191 LPCWSTR szNext = NULL;
192 WCHAR c, szElement[MAX_PATH];
193 LPITEMIDLIST pidlTemp = NULL;
194 CLSID clsid;
196 TRACE("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n", This,
197 hwndOwner, pbc, lpszDisplayName, debugstr_w (lpszDisplayName),
198 pchEaten, ppidl, pdwAttributes);
200 *ppidl = 0;
201 if (pchEaten)
202 *pchEaten = 0; /* strange but like the original */
204 /* handle CLSID paths */
205 if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
207 szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
208 TRACE ("-- element: %s\n", debugstr_w (szElement));
209 SHCLSIDFromStringW (szElement + 2, &clsid);
210 pidlTemp = _ILCreateGuid (PT_GUID, &clsid);
212 /* we can't use PathGetDriveNumberW because we can't have the \\?\ prefix */
213 else if ((c = towupper(lpszDisplayName[0])) >= 'A' && c <= 'Z' &&
214 lpszDisplayName[1] == ':' &&
215 (lpszDisplayName[2] == '\\' || lpszDisplayName[2] == '\0'))
217 /* drive letter has to be uppercase to enable PIDL comparison */
218 szElement[0] = c;
219 szElement[1] = ':';
220 szElement[2] = '\\';
221 szElement[3] = '\0';
222 szNext = &lpszDisplayName[2] + (lpszDisplayName[2] == '\\');
223 pidlTemp = _ILCreateDrive (szElement);
226 if (szNext && *szNext)
228 hr = SHELL32_ParseNextElement (iface, hwndOwner, pbc, &pidlTemp,
229 (LPOLESTR) szNext, pchEaten, pdwAttributes);
231 else if (pidlTemp)
233 if (pdwAttributes && *pdwAttributes)
234 SHELL32_GetItemAttributes (&This->IShellFolder2_iface, pidlTemp, pdwAttributes);
235 hr = S_OK;
238 *ppidl = pidlTemp;
240 TRACE ("(%p)->(-- ret=0x%08lx)\n", This, hr);
242 return hr;
245 /* retrieve a map of drives that should be displayed */
246 static DWORD get_drive_map(void)
248 static DWORD drive_mask;
249 static BOOL init_done = FALSE;
251 if (!init_done)
253 DWORD type, size, data, mask = 0;
254 HKEY hkey;
256 if (!RegOpenKeyW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", &hkey ))
258 size = sizeof(data);
259 if (!RegQueryValueExW( hkey, L"NoDrives", NULL, &type, (LPBYTE)&data, &size ) && type == REG_DWORD)
260 mask |= data;
261 RegCloseKey( hkey );
263 if (!RegOpenKeyW( HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", &hkey ))
265 size = sizeof(data);
266 if (!RegQueryValueExW( hkey, L"NoDrives", NULL, &type, (LPBYTE)&data, &size ) && type == REG_DWORD)
267 mask |= data;
268 RegCloseKey( hkey );
270 drive_mask = mask;
271 init_done = TRUE;
274 return GetLogicalDrives() & ~drive_mask;
277 /**************************************************************************
278 * CreateMyCompEnumList()
280 static BOOL CreateMyCompEnumList(IEnumIDListImpl *list, DWORD dwFlags)
282 BOOL ret = TRUE;
284 TRACE("(%p)->(flags=0x%08lx)\n", list, dwFlags);
286 /* enumerate the folders */
287 if (dwFlags & SHCONTF_FOLDERS)
289 WCHAR wszDriveName[] = L"A:\\";
290 DWORD dwDrivemap = get_drive_map();
291 HKEY hkey;
292 UINT i;
294 while (ret && wszDriveName[0]<='Z')
296 if(dwDrivemap & 0x00000001L)
297 ret = AddToEnumList(list, _ILCreateDrive(wszDriveName));
298 wszDriveName[0]++;
299 dwDrivemap = dwDrivemap >> 1;
302 TRACE("-- (%p)-> enumerate (mycomputer shell extensions)\n",list);
303 for (i=0; i<2; i++) {
304 if (ret && !RegOpenKeyExW(i == 0 ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
305 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\Namespace",
306 0, KEY_READ, &hkey))
308 WCHAR iid[50];
309 int i=0;
311 while (ret)
313 DWORD size;
314 LONG r;
316 size = ARRAY_SIZE(iid);
317 r = RegEnumKeyExW(hkey, i, iid, &size, 0, NULL, NULL, NULL);
318 if (ERROR_SUCCESS == r)
320 /* FIXME: shell extensions, shouldn't the type be
321 * PT_SHELLEXT? */
322 ret = AddToEnumList(list, _ILCreateGuidFromStrW(iid));
323 i++;
325 else if (ERROR_NO_MORE_ITEMS == r)
326 break;
327 else
328 ret = FALSE;
330 RegCloseKey(hkey);
334 return ret;
337 /**************************************************************************
338 * ISF_MyComputer_fnEnumObjects
340 static HRESULT WINAPI ISF_MyComputer_fnEnumObjects (IShellFolder2 *iface,
341 HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
343 IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
344 IEnumIDListImpl *list;
346 TRACE("(%p)->(HWND=%p flags=0x%08lx pplist=%p)\n", This,
347 hwndOwner, dwFlags, ppEnumIDList);
349 if (!(list = IEnumIDList_Constructor()))
350 return E_OUTOFMEMORY;
351 CreateMyCompEnumList(list, dwFlags);
352 *ppEnumIDList = &list->IEnumIDList_iface;
354 TRACE ("-- (%p)->(new ID List: %p)\n", This, *ppEnumIDList);
356 return S_OK;
359 /**************************************************************************
360 * ISF_MyComputer_fnBindToObject
362 static HRESULT WINAPI ISF_MyComputer_fnBindToObject (IShellFolder2 *iface,
363 LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
365 IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
367 TRACE("(%p)->(pidl=%p,%p,%s,%p)\n", This,
368 pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
370 return SHELL32_BindToChild (This->pidlRoot, &CLSID_ShellFSFolder, NULL, pidl, riid, ppvOut);
373 /**************************************************************************
374 * ISF_MyComputer_fnBindToStorage
376 static HRESULT WINAPI ISF_MyComputer_fnBindToStorage (IShellFolder2 * iface,
377 LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
379 IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
381 FIXME("(%p)->(pidl=%p,%p,%s,%p) stub\n", This,
382 pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
384 *ppvOut = NULL;
385 return E_NOTIMPL;
388 /**************************************************************************
389 * ISF_MyComputer_fnCompareIDs
392 static HRESULT WINAPI ISF_MyComputer_fnCompareIDs (IShellFolder2 *iface,
393 LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
395 IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
396 HRESULT hr;
398 TRACE ("(%p)->(0x%08Ix,pidl1=%p,pidl2=%p)\n", This, lParam, pidl1, pidl2);
399 hr = SHELL32_CompareIDs(&This->IShellFolder2_iface, lParam, pidl1, pidl2);
400 TRACE ("-- 0x%08lx\n", hr);
401 return hr;
404 /**************************************************************************
405 * ISF_MyComputer_fnCreateViewObject
407 static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject (IShellFolder2 *iface,
408 HWND hwndOwner, REFIID riid, LPVOID * ppvOut)
410 IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
411 LPSHELLVIEW pShellView;
412 HRESULT hr = E_INVALIDARG;
414 TRACE("(%p)->(hwnd=%p,%s,%p)\n", This,
415 hwndOwner, shdebugstr_guid (riid), ppvOut);
417 if (!ppvOut)
418 return hr;
420 *ppvOut = NULL;
422 if (IsEqualIID (riid, &IID_IDropTarget))
424 WARN ("IDropTarget not implemented\n");
425 hr = E_NOTIMPL;
427 else if (IsEqualIID (riid, &IID_IContextMenu))
429 hr = BackgroundMenu_Constructor((IShellFolder*)iface, FALSE, riid, ppvOut);
431 else if (IsEqualIID (riid, &IID_IShellView))
433 pShellView = IShellView_Constructor ((IShellFolder *) iface);
434 if (pShellView)
436 hr = IShellView_QueryInterface (pShellView, riid, ppvOut);
437 IShellView_Release (pShellView);
440 TRACE ("-- (%p)->(interface=%p)\n", This, ppvOut);
441 return hr;
444 /**************************************************************************
445 * ISF_MyComputer_fnGetAttributesOf
447 static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf (IShellFolder2 * iface,
448 UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut)
450 IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
451 HRESULT hr = S_OK;
453 TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08lx))\n",
454 This, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
456 if (!rgfInOut)
457 return E_INVALIDARG;
458 if (cidl && !apidl)
459 return E_INVALIDARG;
461 if (*rgfInOut == 0)
462 *rgfInOut = ~0;
464 if(cidl == 0){
465 IShellFolder2 *parent = NULL;
466 LPCITEMIDLIST rpidl = NULL;
468 hr = SHBindToParent(This->pidlRoot, &IID_IShellFolder2, (void **)&parent, &rpidl);
469 if(SUCCEEDED(hr)) {
470 SHELL32_GetItemAttributes(parent, rpidl, rgfInOut);
471 IShellFolder2_Release(parent);
473 } else {
474 while (cidl > 0 && *apidl) {
475 pdump (*apidl);
476 SHELL32_GetItemAttributes(&This->IShellFolder2_iface, *apidl, rgfInOut);
477 apidl++;
478 cidl--;
481 /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
482 *rgfInOut &= ~SFGAO_VALIDATE;
484 TRACE ("-- result=0x%08lx\n", *rgfInOut);
485 return hr;
488 /**************************************************************************
489 * ISF_MyComputer_fnGetUIObjectOf
491 * PARAMETERS
492 * hwndOwner [in] Parent window for any output
493 * cidl [in] array size
494 * apidl [in] simple pidl array
495 * riid [in] Requested Interface
496 * prgfInOut [ ] reserved
497 * ppvObject [out] Resulting Interface
500 static HRESULT WINAPI ISF_MyComputer_fnGetUIObjectOf (IShellFolder2 * iface,
501 HWND hwndOwner, UINT cidl, LPCITEMIDLIST * apidl, REFIID riid,
502 UINT * prgfInOut, LPVOID * ppvOut)
504 IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
506 LPITEMIDLIST pidl;
507 IUnknown *pObj = NULL;
508 HRESULT hr = E_INVALIDARG;
510 TRACE("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n", This,
511 hwndOwner, cidl, apidl, shdebugstr_guid (riid), prgfInOut, ppvOut);
513 if (!ppvOut)
514 return hr;
516 *ppvOut = NULL;
518 if (IsEqualIID (riid, &IID_IContextMenu) && (cidl >= 1))
520 return ItemMenu_Constructor((IShellFolder*) iface, This->pidlRoot, apidl, cidl, riid, ppvOut);
522 else if (IsEqualIID (riid, &IID_IDataObject) && (cidl >= 1))
524 pObj = (LPUNKNOWN) IDataObject_Constructor (hwndOwner,
525 This->pidlRoot, apidl, cidl);
526 hr = S_OK;
528 else if (IsEqualIID (riid, &IID_IExtractIconA) && (cidl == 1))
530 pidl = ILCombine (This->pidlRoot, apidl[0]);
531 pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl);
532 SHFree (pidl);
533 hr = S_OK;
535 else if (IsEqualIID (riid, &IID_IExtractIconW) && (cidl == 1))
537 pidl = ILCombine (This->pidlRoot, apidl[0]);
538 pObj = (LPUNKNOWN) IExtractIconW_Constructor (pidl);
539 SHFree (pidl);
540 hr = S_OK;
542 else if (IsEqualIID (riid, &IID_IDropTarget) && (cidl >= 1))
544 hr = IShellFolder2_QueryInterface (iface, &IID_IDropTarget,
545 (LPVOID *) &pObj);
547 else if ((IsEqualIID(riid,&IID_IShellLinkW) ||
548 IsEqualIID(riid,&IID_IShellLinkA)) && (cidl == 1))
550 pidl = ILCombine (This->pidlRoot, apidl[0]);
551 hr = IShellLink_ConstructFromFile(NULL, riid, pidl, &pObj);
552 SHFree (pidl);
554 else
555 hr = E_NOINTERFACE;
557 if (SUCCEEDED(hr) && !pObj)
558 hr = E_OUTOFMEMORY;
560 *ppvOut = pObj;
561 TRACE ("(%p)->hr=0x%08lx\n", This, hr);
562 return hr;
565 /**************************************************************************
566 * ISF_MyComputer_fnGetDisplayNameOf
568 static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf (IShellFolder2 *iface,
569 LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
571 IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
573 LPWSTR pszPath;
574 HRESULT hr = S_OK;
576 TRACE ("(%p)->(pidl=%p,0x%08lx,%p)\n", This, pidl, dwFlags, strRet);
577 pdump (pidl);
579 if (!strRet)
580 return E_INVALIDARG;
582 pszPath = CoTaskMemAlloc((MAX_PATH +1) * sizeof(WCHAR));
583 if (!pszPath)
584 return E_OUTOFMEMORY;
586 pszPath[0] = 0;
588 if (!pidl->mkid.cb)
590 /* parsing name like ::{...} */
591 pszPath[0] = ':';
592 pszPath[1] = ':';
593 SHELL32_GUIDToStringW(&CLSID_MyComputer, &pszPath[2]);
595 else if (_ILIsPidlSimple(pidl))
597 /* take names of special folders only if its only this folder */
598 if (_ILIsSpecialFolder(pidl))
600 GUID const *clsid;
602 clsid = _ILGetGUIDPointer (pidl);
603 if (clsid)
605 if ((GET_SHGDN_FOR (dwFlags) & (SHGDN_FORPARSING | SHGDN_FORADDRESSBAR)) == SHGDN_FORPARSING)
607 BOOL bWantsForParsing = FALSE;
608 WCHAR szRegPath[100];
609 LONG r;
612 * We can only get a filesystem path from a shellfolder
613 * if the value WantsFORPARSING exists in
614 * CLSID\\{...}\\shellfolder
615 * exception: the MyComputer folder has this keys not
616 * but like any filesystem backed
617 * folder it needs these behaviour
619 * Get the "WantsFORPARSING" flag from the registry
622 lstrcpyW (szRegPath, L"CLSID\\");
623 SHELL32_GUIDToStringW (clsid, &szRegPath[6]);
624 lstrcatW (szRegPath, L"\\shellfolder");
625 r = SHGetValueW (HKEY_CLASSES_ROOT, szRegPath, L"WantsForParsing", NULL, NULL, NULL);
626 if (r == ERROR_SUCCESS)
627 bWantsForParsing = TRUE;
629 if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
630 bWantsForParsing)
633 * We need the filesystem path to the destination folder
634 * Only the folder itself can know it
636 hr = SHELL32_GetDisplayNameOfChild (iface, pidl,
637 dwFlags, pszPath, MAX_PATH);
639 else
641 LPWSTR p = pszPath;
643 /* parsing name like ::{...} */
644 p[0] = ':';
645 p[1] = ':';
646 p += 2;
647 p += SHELL32_GUIDToStringW(&CLSID_MyComputer, p);
649 /* \:: */
650 p[0] = '\\';
651 p[1] = ':';
652 p[2] = ':';
653 p += 3;
654 SHELL32_GUIDToStringW(clsid, p);
657 else
659 /* user friendly name */
660 HCR_GetClassNameW (clsid, pszPath, MAX_PATH);
663 else
665 /* append my own path */
666 _ILSimpleGetTextW (pidl, pszPath, MAX_PATH);
669 else if (_ILIsDrive(pidl))
671 _ILSimpleGetTextW (pidl, pszPath, MAX_PATH); /* append my own path */
673 /* long view "lw_name (C:)" */
674 if (!(dwFlags & SHGDN_FORPARSING))
676 WCHAR wszDrive[32 /* label */ + 6 /* ' (C:)'\0 */] = {0};
678 GetVolumeInformationW (pszPath, wszDrive, ARRAY_SIZE(wszDrive) - 5, NULL, NULL,
679 NULL, NULL, 0);
680 lstrcatW (wszDrive, L" (");
681 lstrcpynW (wszDrive + lstrlenW(wszDrive), pszPath, 3);
682 lstrcatW (wszDrive, L")");
683 lstrcpyW (pszPath, wszDrive);
686 else
688 /* Neither a shell namespace extension nor a drive letter. */
689 ERR("Wrong pidl type\n");
690 CoTaskMemFree(pszPath);
691 return E_INVALIDARG;
694 else
696 /* Complex pidl. Let the child folder do the work */
697 hr = SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, pszPath, MAX_PATH);
700 if (SUCCEEDED (hr))
702 /* Win9x always returns ANSI strings, NT always returns Unicode strings */
703 if (GetVersion() & 0x80000000)
705 strRet->uType = STRRET_CSTR;
706 if (!WideCharToMultiByte(CP_ACP, 0, pszPath, -1, strRet->u.cStr, MAX_PATH,
707 NULL, NULL))
708 strRet->u.cStr[0] = '\0';
709 CoTaskMemFree(pszPath);
711 else
713 strRet->uType = STRRET_WSTR;
714 strRet->u.pOleStr = pszPath;
717 else
718 CoTaskMemFree(pszPath);
720 TRACE ("-- (%p)->(%s)\n", This, strRet->uType == STRRET_CSTR ? strRet->u.cStr : debugstr_w(strRet->u.pOleStr));
721 return hr;
724 /**************************************************************************
725 * ISF_MyComputer_fnSetNameOf
726 * Changes the name of a file object or subfolder, possibly changing its item
727 * identifier in the process.
729 * PARAMETERS
730 * hwndOwner [in] Owner window for output
731 * pidl [in] simple pidl of item to change
732 * lpszName [in] the items new display name
733 * dwFlags [in] SHGNO formatting flags
734 * ppidlOut [out] simple pidl returned
736 static HRESULT WINAPI ISF_MyComputer_fnSetNameOf (
737 IShellFolder2 * iface, HWND hwndOwner, LPCITEMIDLIST pidl,
738 LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut)
740 IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
741 FIXME ("(%p)->(%p,pidl=%p,%s,%lu,%p)\n", This,
742 hwndOwner, pidl, debugstr_w (lpName), dwFlags, pPidlOut);
743 return E_FAIL;
746 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID(IShellFolder2 *iface, GUID *guid)
748 IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
749 TRACE("(%p)->(%p)\n", This, guid);
750 return E_NOTIMPL;
752 static HRESULT WINAPI ISF_MyComputer_fnEnumSearches (
753 IShellFolder2 * iface, IEnumExtraSearch ** ppenum)
755 IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
756 FIXME ("(%p)\n", This);
757 return E_NOTIMPL;
760 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumn(IShellFolder2 *iface, DWORD reserved,
761 ULONG *sort, ULONG *display)
763 IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
765 TRACE("(%p)->(%#lx, %p, %p)\n", This, reserved, sort, display);
767 return E_NOTIMPL;
770 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumnState (
771 IShellFolder2 * iface, UINT iColumn, DWORD * pcsFlags)
773 IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
775 TRACE ("(%p)->(%d %p)\n", This, iColumn, pcsFlags);
777 if (!pcsFlags || iColumn >= ARRAY_SIZE(mycomputer_header))
778 return E_INVALIDARG;
780 *pcsFlags = mycomputer_header[iColumn].pcsFlags;
782 return S_OK;
785 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx (IShellFolder2 * iface,
786 LPCITEMIDLIST pidl, const SHCOLUMNID * pscid, VARIANT * pv)
788 IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
789 FIXME ("(%p)\n", This);
790 return E_NOTIMPL;
793 /* FIXME: drive size >4GB is rolling over */
794 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf (IShellFolder2 *iface,
795 LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS *psd)
797 IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
798 char szPath[MAX_PATH];
799 ULARGE_INTEGER ulBytes;
800 HRESULT hr = S_OK;
802 TRACE ("(%p)->(%p %i %p)\n", This, pidl, iColumn, psd);
804 if (!psd || iColumn >= ARRAY_SIZE(mycomputer_header))
805 return E_INVALIDARG;
807 if (!pidl)
808 return SHELL32_GetColumnDetails(mycomputer_header, iColumn, psd);
810 psd->str.u.cStr[0] = 0;
811 psd->str.uType = STRRET_CSTR;
813 switch (iColumn)
815 case 2: /* total size */
816 if (_ILIsDrive (pidl))
818 _ILSimpleGetText (pidl, szPath, MAX_PATH);
819 GetDiskFreeSpaceExA (szPath, NULL, &ulBytes, NULL);
820 StrFormatByteSizeA (ulBytes.u.LowPart, psd->str.u.cStr, MAX_PATH);
822 break;
823 case 3: /* free size */
824 if (_ILIsDrive (pidl))
826 _ILSimpleGetText (pidl, szPath, MAX_PATH);
827 GetDiskFreeSpaceExA (szPath, &ulBytes, NULL, NULL);
828 StrFormatByteSizeA (ulBytes.u.LowPart, psd->str.u.cStr, MAX_PATH);
830 break;
832 default:
833 return shellfolder_get_file_details( iface, pidl, mycomputer_header, iColumn, psd );
836 return hr;
839 static HRESULT WINAPI ISF_MyComputer_fnMapColumnToSCID (IShellFolder2 *iface, UINT column, SHCOLUMNID *scid)
841 IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
843 TRACE("(%p)->(%u %p)\n", This, column, scid);
845 if (column >= ARRAY_SIZE(mycomputer_header))
846 return E_INVALIDARG;
848 return shellfolder_map_column_to_scid(mycomputer_header, column, scid);
851 static const IShellFolder2Vtbl vt_ShellFolder2 =
853 ISF_MyComputer_fnQueryInterface,
854 ISF_MyComputer_fnAddRef,
855 ISF_MyComputer_fnRelease,
856 ISF_MyComputer_fnParseDisplayName,
857 ISF_MyComputer_fnEnumObjects,
858 ISF_MyComputer_fnBindToObject,
859 ISF_MyComputer_fnBindToStorage,
860 ISF_MyComputer_fnCompareIDs,
861 ISF_MyComputer_fnCreateViewObject,
862 ISF_MyComputer_fnGetAttributesOf,
863 ISF_MyComputer_fnGetUIObjectOf,
864 ISF_MyComputer_fnGetDisplayNameOf,
865 ISF_MyComputer_fnSetNameOf,
866 /* ShellFolder2 */
867 ISF_MyComputer_fnGetDefaultSearchGUID,
868 ISF_MyComputer_fnEnumSearches,
869 ISF_MyComputer_fnGetDefaultColumn,
870 ISF_MyComputer_fnGetDefaultColumnState,
871 ISF_MyComputer_fnGetDetailsEx,
872 ISF_MyComputer_fnGetDetailsOf,
873 ISF_MyComputer_fnMapColumnToSCID
876 /************************************************************************
877 * IMCFldr_PersistFolder2_QueryInterface
879 static HRESULT WINAPI IMCFldr_PersistFolder2_QueryInterface (
880 IPersistFolder2 * iface, REFIID iid, LPVOID * ppvObj)
882 IMyComputerFolderImpl *This = impl_from_IPersistFolder2(iface);
883 TRACE ("(%p)\n", This);
884 return IShellFolder2_QueryInterface (&This->IShellFolder2_iface, iid, ppvObj);
887 /************************************************************************
888 * IMCFldr_PersistFolder2_AddRef
890 static ULONG WINAPI IMCFldr_PersistFolder2_AddRef (IPersistFolder2 * iface)
892 IMyComputerFolderImpl *This = impl_from_IPersistFolder2(iface);
893 TRACE ("(%p)->(count=%lu)\n", This, This->ref);
894 return IShellFolder2_AddRef (&This->IShellFolder2_iface);
897 /************************************************************************
898 * ISFPersistFolder_Release
900 static ULONG WINAPI IMCFldr_PersistFolder2_Release (IPersistFolder2 * iface)
902 IMyComputerFolderImpl *This = impl_from_IPersistFolder2(iface);
903 TRACE ("(%p)->(count=%lu)\n", This, This->ref);
904 return IShellFolder2_Release (&This->IShellFolder2_iface);
907 /************************************************************************
908 * IMCFldr_PersistFolder2_GetClassID
910 static HRESULT WINAPI IMCFldr_PersistFolder2_GetClassID (
911 IPersistFolder2 * iface, CLSID * lpClassId)
913 IMyComputerFolderImpl *This = impl_from_IPersistFolder2(iface);
915 TRACE ("(%p)\n", This);
917 if (!lpClassId)
918 return E_POINTER;
919 *lpClassId = CLSID_MyComputer;
921 return S_OK;
924 /************************************************************************
925 * IMCFldr_PersistFolder2_Initialize
927 * NOTES: it makes no sense to change the pidl
929 static HRESULT WINAPI IMCFldr_PersistFolder2_Initialize (
930 IPersistFolder2 * iface, LPCITEMIDLIST pidl)
932 IMyComputerFolderImpl *This = impl_from_IPersistFolder2(iface);
933 TRACE ("(%p)->(%p)\n", This, pidl);
934 return E_NOTIMPL;
937 /**************************************************************************
938 * IPersistFolder2_fnGetCurFolder
940 static HRESULT WINAPI IMCFldr_PersistFolder2_GetCurFolder (
941 IPersistFolder2 * iface, LPITEMIDLIST * pidl)
943 IMyComputerFolderImpl *This = impl_from_IPersistFolder2(iface);
945 TRACE ("(%p)->(%p)\n", This, pidl);
947 if (!pidl)
948 return E_POINTER;
949 *pidl = ILClone (This->pidlRoot);
950 return S_OK;
953 static const IPersistFolder2Vtbl vt_PersistFolder2 =
955 IMCFldr_PersistFolder2_QueryInterface,
956 IMCFldr_PersistFolder2_AddRef,
957 IMCFldr_PersistFolder2_Release,
958 IMCFldr_PersistFolder2_GetClassID,
959 IMCFldr_PersistFolder2_Initialize,
960 IMCFldr_PersistFolder2_GetCurFolder