2 * Virtual Workplace folder
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998, 1999, 2002 Juergen Schmied
6 * Copyright 2009 Andrew Hill
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.
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.
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
25 WINE_DEFAULT_DEBUG_CHANNEL (shell
);
28 CDrivesFolder should create a CRegFolder to represent the virtual items that exist only in
29 the registry. The CRegFolder is aggregated by the CDrivesFolder.
30 The CDrivesFolderEnum class should enumerate only drives on the system. Since the CRegFolder
31 implementation of IShellFolder::EnumObjects enumerates the virtual items, the
32 CDrivesFolderEnum is only responsible for returning the physical items.
34 2. At least on my XP system, the drive pidls returned are of type PT_DRIVE1, not PT_DRIVE
35 3. The parsing name returned for my computer is incorrect. It should be "My Computer"
38 /***********************************************************************
39 * IShellFolder implementation
42 HRESULT
CDrivesExtractIcon_CreateInstance(IShellFolder
* psf
, LPCITEMIDLIST pidl
, REFIID riid
, LPVOID
* ppvOut
)
44 CComPtr
<IDefaultExtractIconInit
> initIcon
;
45 HRESULT hr
= SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit
, &initIcon
));
49 CHAR
* pszDrive
= _ILGetDataPointer(pidl
)->u
.drive
.szDriveName
;
50 WCHAR wTemp
[MAX_PATH
];
55 switch(GetDriveTypeA(pszDrive
))
58 icon_idx
= IDI_SHELL_3_14_FLOPPY
;
61 icon_idx
= IDI_SHELL_CDROM
;
64 icon_idx
= IDI_SHELL_NETDRIVE
;
67 icon_idx
= IDI_SHELL_RAMDISK
;
69 case DRIVE_NO_ROOT_DIR
:
70 icon_idx
= IDI_SHELL_CDROM
;
77 initIcon
->SetNormalIcon(swShell32Name
, -icon_idx
);
81 if (HCR_GetIconW(L
"Drive", wTemp
, NULL
, MAX_PATH
, &icon_idx
))
82 initIcon
->SetNormalIcon(wTemp
, icon_idx
);
84 initIcon
->SetNormalIcon(swShell32Name
, -IDI_SHELL_DRIVE
);
87 return initIcon
->QueryInterface(riid
, ppvOut
);
90 class CDrivesFolderEnum
:
91 public CEnumIDListBase
96 HRESULT WINAPI
Initialize(HWND hwndOwner
, DWORD dwFlags
);
97 BOOL
CreateMyCompEnumList(DWORD dwFlags
);
99 BEGIN_COM_MAP(CDrivesFolderEnum
)
100 COM_INTERFACE_ENTRY_IID(IID_IEnumIDList
, IEnumIDList
)
104 /***********************************************************************
105 * IShellFolder [MyComputer] implementation
108 static const shvheader MyComputerSFHeader
[] = {
109 {IDS_SHV_COLUMN1
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 15},
110 {IDS_SHV_COLUMN3
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 10},
111 {IDS_SHV_COLUMN6
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10},
112 {IDS_SHV_COLUMN7
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10},
115 #define MYCOMPUTERSHELLVIEWCOLUMNS 4
117 static const DWORD dwComputerAttributes
=
118 SFGAO_CANRENAME
| SFGAO_CANDELETE
| SFGAO_HASPROPSHEET
| SFGAO_DROPTARGET
|
119 SFGAO_FILESYSANCESTOR
| SFGAO_FOLDER
| SFGAO_HASSUBFOLDER
| SFGAO_CANLINK
;
120 static const DWORD dwControlPanelAttributes
=
121 SFGAO_HASSUBFOLDER
| SFGAO_FOLDER
| SFGAO_CANLINK
;
122 static const DWORD dwDriveAttributes
=
123 SFGAO_HASSUBFOLDER
| SFGAO_FILESYSTEM
| SFGAO_FOLDER
| SFGAO_FILESYSANCESTOR
|
124 SFGAO_DROPTARGET
| SFGAO_HASPROPSHEET
| SFGAO_CANRENAME
| SFGAO_CANLINK
;
126 CDrivesFolderEnum::CDrivesFolderEnum()
130 CDrivesFolderEnum::~CDrivesFolderEnum()
134 HRESULT WINAPI
CDrivesFolderEnum::Initialize(HWND hwndOwner
, DWORD dwFlags
)
136 if (CreateMyCompEnumList(dwFlags
) == FALSE
)
142 /**************************************************************************
143 * CDrivesFolderEnum::CreateMyCompEnumList()
146 BOOL
CDrivesFolderEnum::CreateMyCompEnumList(DWORD dwFlags
)
149 static const WCHAR MyComputer_NameSpaceW
[] = L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\Namespace";
151 TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags
);
153 /* enumerate the folders */
154 if (dwFlags
& SHCONTF_FOLDERS
)
156 WCHAR wszDriveName
[] = {'A', ':', '\\', '\0'};
157 DWORD dwDrivemap
= GetLogicalDrives();
161 while (bRet
&& wszDriveName
[0] <= 'Z')
163 if(dwDrivemap
& 0x00000001L
)
164 bRet
= AddToEnumList(_ILCreateDrive(wszDriveName
));
166 dwDrivemap
= dwDrivemap
>> 1;
169 TRACE("-- (%p)-> enumerate (mycomputer shell extensions)\n", this);
170 for (i
= 0; i
< 2; i
++)
172 if (bRet
&& ERROR_SUCCESS
== RegOpenKeyExW(i
== 0 ? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
,
173 MyComputer_NameSpaceW
, 0, KEY_READ
, &hKey
))
182 dwSize
= sizeof(wszBuf
) / sizeof(wszBuf
[0]);
183 ErrorCode
= RegEnumKeyExW(hKey
, j
, wszBuf
, &dwSize
, 0, NULL
, NULL
, NULL
);
184 if (ERROR_SUCCESS
== ErrorCode
)
186 if (wszBuf
[0] != L
'{')
188 dwSize
= sizeof(wszBuf
);
189 RegGetValueW(hKey
, wszBuf
, NULL
, RRF_RT_REG_SZ
, NULL
, wszBuf
, &dwSize
);
192 /* FIXME: shell extensions - the type should be PT_SHELLEXT (tested) */
193 pidl
= _ILCreateGuidFromStrW(wszBuf
);
195 bRet
= AddToEnumList(pidl
);
197 ERR("Invalid MyComputer namespace extesion: %s\n", wszBuf
);
200 else if (ERROR_NO_MORE_ITEMS
== ErrorCode
)
212 CDrivesFolder::CDrivesFolder()
217 CDrivesFolder::~CDrivesFolder()
219 TRACE ("-- destroying IShellFolder(%p)\n", this);
223 HRESULT WINAPI
CDrivesFolder::FinalConstruct()
225 pidlRoot
= _ILCreateMyComputer(); /* my qualified pidl */
226 if (pidlRoot
== NULL
)
227 return E_OUTOFMEMORY
;
229 HRESULT hr
= CRegFolder_CreateInstance(&CLSID_MyComputer
,
231 L
"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}",
232 IID_PPV_ARG(IShellFolder2
, &m_regFolder
));
237 /**************************************************************************
238 * CDrivesFolder::ParseDisplayName
240 HRESULT WINAPI
CDrivesFolder::ParseDisplayName(HWND hwndOwner
, LPBC pbc
, LPOLESTR lpszDisplayName
,
241 DWORD
* pchEaten
, PIDLIST_RELATIVE
* ppidl
, DWORD
* pdwAttributes
)
243 HRESULT hr
= E_INVALIDARG
;
244 LPCWSTR szNext
= NULL
;
245 LPITEMIDLIST pidlTemp
= NULL
;
247 TRACE("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n", this,
248 hwndOwner
, pbc
, lpszDisplayName
, debugstr_w (lpszDisplayName
),
249 pchEaten
, ppidl
, pdwAttributes
);
253 *pchEaten
= 0; /* strange but like the original */
255 /* handle CLSID paths */
256 if (lpszDisplayName
[0] == ':' && lpszDisplayName
[1] == ':')
257 return m_regFolder
->ParseDisplayName(hwndOwner
, pbc
, lpszDisplayName
, pchEaten
, ppidl
, pdwAttributes
);
259 if (PathGetDriveNumberW(lpszDisplayName
) < 0)
262 pidlTemp
= _ILCreateDrive(lpszDisplayName
);
264 return E_OUTOFMEMORY
;
266 if (lpszDisplayName
[2] == L
'\\')
268 szNext
= &lpszDisplayName
[3];
271 if (szNext
&& *szNext
)
273 hr
= SHELL32_ParseNextElement (this, hwndOwner
, pbc
, &pidlTemp
,
274 (LPOLESTR
) szNext
, pchEaten
, pdwAttributes
);
279 if (pdwAttributes
&& *pdwAttributes
)
281 if (_ILIsDrive(pidlTemp
))
282 *pdwAttributes
&= dwDriveAttributes
;
283 else if (_ILIsSpecialFolder(pidlTemp
))
284 m_regFolder
->GetAttributesOf(1, &pidlTemp
, pdwAttributes
);
286 ERR("Got an unkown pidl here!\n");
292 TRACE ("(%p)->(-- ret=0x%08x)\n", this, hr
);
297 /**************************************************************************
298 * CDrivesFolder::EnumObjects
300 HRESULT WINAPI
CDrivesFolder::EnumObjects(HWND hwndOwner
, DWORD dwFlags
, LPENUMIDLIST
*ppEnumIDList
)
302 return ShellObjectCreatorInit
<CDrivesFolderEnum
>(hwndOwner
, dwFlags
, IID_IEnumIDList
, ppEnumIDList
);
305 /**************************************************************************
306 * CDrivesFolder::BindToObject
308 HRESULT WINAPI
CDrivesFolder::BindToObject(PCUIDLIST_RELATIVE pidl
, LPBC pbcReserved
, REFIID riid
, LPVOID
*ppvOut
)
310 TRACE("(%p)->(pidl=%p,%p,%s,%p)\n", this,
311 pidl
, pbcReserved
, shdebugstr_guid(&riid
), ppvOut
);
313 if (_ILIsSpecialFolder(pidl
))
314 return m_regFolder
->BindToObject(pidl
, pbcReserved
, riid
, ppvOut
);
316 LPITEMIDLIST pidlChild
= ILCloneFirst (pidl
);
318 return E_OUTOFMEMORY
;
320 CComPtr
<IShellFolder
> psf
;
321 HRESULT hr
= SHELL32_CoCreateInitSF(pidlRoot
,
324 &CLSID_ShellFSFolder
,
326 IID_PPV_ARG(IShellFolder
, &psf
));
333 if (_ILIsPidlSimple (pidl
))
335 return psf
->QueryInterface(riid
, ppvOut
);
339 return psf
->BindToObject(ILGetNext (pidl
), pbcReserved
, riid
, ppvOut
);
343 /**************************************************************************
344 * CDrivesFolder::BindToStorage
346 HRESULT WINAPI
CDrivesFolder::BindToStorage(PCUIDLIST_RELATIVE pidl
, LPBC pbcReserved
, REFIID riid
, LPVOID
*ppvOut
)
348 FIXME("(%p)->(pidl=%p,%p,%s,%p) stub\n", this,
349 pidl
, pbcReserved
, shdebugstr_guid (&riid
), ppvOut
);
355 /**************************************************************************
356 * CDrivesFolder::CompareIDs
359 HRESULT WINAPI
CDrivesFolder::CompareIDs(LPARAM lParam
, PCUIDLIST_RELATIVE pidl1
, PCUIDLIST_RELATIVE pidl2
)
361 if (!pidl1
|| !pidl2
)
363 ERR("Got null pidl pointer (%Ix %p %p)!\n", lParam
, pidl1
, pidl2
);
367 if (_ILIsSpecialFolder(pidl1
) || _ILIsSpecialFolder(pidl2
))
368 m_regFolder
->CompareIDs(lParam
, pidl1
, pidl2
);
370 if (!_ILIsDrive(pidl1
) || !_ILIsDrive(pidl2
) || LOWORD(lParam
) >= MYCOMPUTERSHELLVIEWCOLUMNS
)
373 CHAR
* pszDrive1
= _ILGetDataPointer(pidl1
)->u
.drive
.szDriveName
;
374 CHAR
* pszDrive2
= _ILGetDataPointer(pidl2
)->u
.drive
.szDriveName
;
377 switch(LOWORD(lParam
))
381 result
= stricmp(pszDrive1
, pszDrive2
);
382 return MAKE_COMPARE_HRESULT(result
);
386 return SHELL32_CompareDetails(this, lParam
, pidl1
, pidl2
);
389 case 3: /* Size Available */
391 ULARGE_INTEGER Drive1Available
, Drive1Total
, Drive2Available
, Drive2Total
;
393 if (GetVolumeInformationA(pszDrive1
, NULL
, 0, NULL
, NULL
, NULL
, NULL
, 0))
394 GetDiskFreeSpaceExA(pszDrive1
, &Drive1Available
, &Drive1Total
, NULL
);
396 Drive1Available
.QuadPart
= Drive1Total
.QuadPart
= 0;
398 if (GetVolumeInformationA(pszDrive2
, NULL
, 0, NULL
, NULL
, NULL
, NULL
, 0))
399 GetDiskFreeSpaceExA(pszDrive2
, &Drive2Available
, &Drive2Total
, NULL
);
401 Drive2Available
.QuadPart
= Drive2Total
.QuadPart
= 0;
404 if (lParam
== 2) /* Size */
405 Diff
.QuadPart
= Drive1Total
.QuadPart
- Drive2Total
.QuadPart
;
406 else /* Size available */
407 Diff
.QuadPart
= Drive1Available
.QuadPart
- Drive2Available
.QuadPart
;
409 return MAKE_COMPARE_HRESULT(Diff
.QuadPart
);
415 /**************************************************************************
416 * CDrivesFolder::CreateViewObject
418 HRESULT WINAPI
CDrivesFolder::CreateViewObject(HWND hwndOwner
, REFIID riid
, LPVOID
* ppvOut
)
420 CComPtr
<IShellView
> pShellView
;
421 HRESULT hr
= E_INVALIDARG
;
423 TRACE("(%p)->(hwnd=%p,%s,%p)\n", this,
424 hwndOwner
, shdebugstr_guid (&riid
), ppvOut
);
431 if (IsEqualIID(riid
, IID_IDropTarget
))
433 WARN("IDropTarget not implemented\n");
436 else if (IsEqualIID(riid
, IID_IContextMenu
))
438 WARN("IContextMenu not implemented\n");
441 else if (IsEqualIID(riid
, IID_IShellView
))
443 hr
= CDefView_Constructor(this, riid
, ppvOut
);
445 TRACE ("-- (%p)->(interface=%p)\n", this, ppvOut
);
449 static BOOL
_ILIsControlPanel(LPCITEMIDLIST pidl
)
451 GUID
*guid
= _ILGetGUIDPointer(pidl
);
453 TRACE("(%p)\n", pidl
);
456 return IsEqualIID(*guid
, CLSID_ControlPanel
);
460 /**************************************************************************
461 * CDrivesFolder::GetAttributesOf
463 HRESULT WINAPI
CDrivesFolder::GetAttributesOf(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, DWORD
* rgfInOut
)
465 TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
466 this, cidl
, apidl
, rgfInOut
, rgfInOut
? *rgfInOut
: 0);
474 /* FIXME: always add SFGAO_CANLINK */
476 *rgfInOut
&= dwComputerAttributes
;
479 for (UINT i
= 0; i
< cidl
; ++i
)
481 if (_ILIsDrive(apidl
[i
]))
482 *rgfInOut
&= dwDriveAttributes
;
483 else if (_ILIsControlPanel(apidl
[i
]))
484 *rgfInOut
&= dwControlPanelAttributes
;
485 else if (_ILIsSpecialFolder(*apidl
))
486 m_regFolder
->GetAttributesOf(1, &apidl
[i
], rgfInOut
);
488 ERR("Got unknown pidl type!\n");
492 /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
493 *rgfInOut
&= ~SFGAO_VALIDATE
;
495 TRACE ("-- result=0x%08x\n", *rgfInOut
);
499 /**************************************************************************
500 * CDrivesFolder::GetUIObjectOf
503 * hwndOwner [in] Parent window for any output
504 * cidl [in] array size
505 * apidl [in] simple pidl array
506 * riid [in] Requested Interface
507 * prgfInOut [ ] reserved
508 * ppvObject [out] Resulting Interface
511 HRESULT WINAPI
CDrivesFolder::GetUIObjectOf(HWND hwndOwner
,
512 UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
,
513 REFIID riid
, UINT
*prgfInOut
, LPVOID
*ppvOut
)
516 HRESULT hr
= E_INVALIDARG
;
518 TRACE("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n", this,
519 hwndOwner
, cidl
, apidl
, shdebugstr_guid (&riid
), prgfInOut
, ppvOut
);
526 if (IsEqualIID (riid
, IID_IContextMenu
) && (cidl
>= 1))
528 hr
= CDefFolderMenu_Create2(pidlRoot
, hwndOwner
, cidl
, apidl
, (IShellFolder
*)this, NULL
, 0, NULL
, (IContextMenu
**)&pObj
);
530 else if (IsEqualIID (riid
, IID_IDataObject
) && (cidl
>= 1))
532 hr
= IDataObject_Constructor (hwndOwner
,
533 pidlRoot
, apidl
, cidl
, (IDataObject
**)&pObj
);
535 else if ((IsEqualIID (riid
, IID_IExtractIconA
) || IsEqualIID (riid
, IID_IExtractIconW
)) && (cidl
== 1))
537 if (_ILIsDrive(apidl
[0]))
538 hr
= CDrivesExtractIcon_CreateInstance(this, apidl
[0], riid
, &pObj
);
540 hr
= m_regFolder
->GetUIObjectOf(hwndOwner
, cidl
, apidl
, riid
, prgfInOut
, &pObj
);
542 else if (IsEqualIID (riid
, IID_IDropTarget
) && (cidl
>= 1))
544 IDropTarget
* pDt
= NULL
;
545 hr
= this->QueryInterface(IID_PPV_ARG(IDropTarget
, &pDt
));
551 if (SUCCEEDED(hr
) && !pObj
)
555 TRACE ("(%p)->hr=0x%08x\n", this, hr
);
559 /**************************************************************************
560 * CDrivesFolder::GetDisplayNameOf
562 HRESULT WINAPI
CDrivesFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl
, DWORD dwFlags
, LPSTRRET strRet
)
567 TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl
, dwFlags
, strRet
);
573 if (!_ILIsPidlSimple (pidl
))
575 return SHELL32_GetDisplayNameOfChild(this, pidl
, dwFlags
, strRet
);
577 else if (_ILIsSpecialFolder(pidl
))
579 return m_regFolder
->GetDisplayNameOf(pidl
, dwFlags
, strRet
);
581 else if (!_ILIsDrive(pidl
))
583 ERR("Wrong pidl type\n");
587 pszPath
= (LPWSTR
)CoTaskMemAlloc((MAX_PATH
+ 1) * sizeof(WCHAR
));
589 return E_OUTOFMEMORY
;
593 _ILSimpleGetTextW(pidl
, pszPath
, MAX_PATH
); /* append my own path */
594 /* long view "lw_name (C:)" */
595 if (!(dwFlags
& SHGDN_FORPARSING
))
597 WCHAR wszDrive
[18] = {0};
598 DWORD dwVolumeSerialNumber
, dwMaximumComponentLength
, dwFileSystemFlags
;
599 static const WCHAR wszOpenBracket
[] = {' ', '(', 0};
600 static const WCHAR wszCloseBracket
[] = {')', 0};
602 lstrcpynW(wszDrive
, pszPath
, 4);
604 GetVolumeInformationW(wszDrive
, pszPath
,
606 &dwVolumeSerialNumber
,
607 &dwMaximumComponentLength
, &dwFileSystemFlags
, NULL
, 0);
608 pszPath
[MAX_PATH
-1] = L
'\0';
609 if (!wcslen(pszPath
))
611 UINT DriveType
, ResourceId
;
612 DriveType
= GetDriveTypeW(wszDrive
);
616 ResourceId
= IDS_DRIVE_FIXED
;
619 ResourceId
= IDS_DRIVE_NETWORK
;
622 ResourceId
= IDS_DRIVE_CDROM
;
629 dwFileSystemFlags
= LoadStringW(shell32_hInstance
, ResourceId
, pszPath
, MAX_PATH
);
630 if (dwFileSystemFlags
> MAX_PATH
- 7)
631 pszPath
[MAX_PATH
-7] = L
'\0';
634 wcscat (pszPath
, wszOpenBracket
);
636 wcscat (pszPath
, wszDrive
);
637 wcscat (pszPath
, wszCloseBracket
);
642 strRet
->uType
= STRRET_WSTR
;
643 strRet
->pOleStr
= pszPath
;
646 CoTaskMemFree(pszPath
);
648 TRACE("-- (%p)->(%s)\n", this, strRet
->uType
== STRRET_CSTR
? strRet
->cStr
: debugstr_w(strRet
->pOleStr
));
652 /**************************************************************************
653 * CDrivesFolder::SetNameOf
654 * Changes the name of a file object or subfolder, possibly changing its item
655 * identifier in the process.
658 * hwndOwner [in] Owner window for output
659 * pidl [in] simple pidl of item to change
660 * lpszName [in] the items new display name
661 * dwFlags [in] SHGNO formatting flags
662 * ppidlOut [out] simple pidl returned
664 HRESULT WINAPI
CDrivesFolder::SetNameOf(HWND hwndOwner
, PCUITEMID_CHILD pidl
,
665 LPCOLESTR lpName
, DWORD dwFlags
, PITEMID_CHILD
*pPidlOut
)
669 if (_ILIsDrive(pidl
))
671 if (_ILSimpleGetTextW(pidl
, szName
, _countof(szName
)))
672 SetVolumeLabelW(szName
, lpName
);
674 *pPidlOut
= _ILCreateDrive(szName
);
678 return m_regFolder
->SetNameOf(hwndOwner
, pidl
, lpName
, dwFlags
, pPidlOut
);
681 HRESULT WINAPI
CDrivesFolder::GetDefaultSearchGUID(GUID
* pguid
)
683 FIXME ("(%p)\n", this);
687 HRESULT WINAPI
CDrivesFolder::EnumSearches(IEnumExtraSearch
** ppenum
)
689 FIXME ("(%p)\n", this);
693 HRESULT WINAPI
CDrivesFolder::GetDefaultColumn (DWORD dwRes
, ULONG
*pSort
, ULONG
*pDisplay
)
695 TRACE ("(%p)\n", this);
704 HRESULT WINAPI
CDrivesFolder::GetDefaultColumnState(UINT iColumn
, DWORD
* pcsFlags
)
706 TRACE ("(%p)\n", this);
708 if (!pcsFlags
|| iColumn
>= MYCOMPUTERSHELLVIEWCOLUMNS
)
710 *pcsFlags
= MyComputerSFHeader
[iColumn
].pcsFlags
;
714 HRESULT WINAPI
CDrivesFolder::GetDetailsEx(PCUITEMID_CHILD pidl
, const SHCOLUMNID
* pscid
, VARIANT
* pv
)
716 FIXME ("(%p)\n", this);
720 HRESULT WINAPI
CDrivesFolder::GetDetailsOf(PCUITEMID_CHILD pidl
, UINT iColumn
, SHELLDETAILS
*psd
)
724 TRACE ("(%p)->(%p %i %p)\n", this, pidl
, iColumn
, psd
);
726 if (!psd
|| iColumn
>= MYCOMPUTERSHELLVIEWCOLUMNS
)
731 psd
->fmt
= MyComputerSFHeader
[iColumn
].fmt
;
732 psd
->cxChar
= MyComputerSFHeader
[iColumn
].cxChar
;
733 return SHSetStrRet(&psd
->str
, MyComputerSFHeader
[iColumn
].colnameid
);
735 else if (_ILIsSpecialFolder(pidl
))
737 return m_regFolder
->GetDetailsOf(pidl
, iColumn
, psd
);
741 char szPath
[MAX_PATH
];
742 ULARGE_INTEGER ulBytes
;
744 psd
->str
.cStr
[0] = 0x00;
745 psd
->str
.uType
= STRRET_CSTR
;
749 hr
= GetDisplayNameOf(pidl
, SHGDN_NORMAL
| SHGDN_INFOLDER
, &psd
->str
);
752 _ILGetFileType(pidl
, psd
->str
.cStr
, MAX_PATH
);
754 case 2: /* total size */
755 _ILSimpleGetText (pidl
, szPath
, MAX_PATH
);
756 if (GetVolumeInformationA(szPath
, NULL
, 0, NULL
, NULL
, NULL
, NULL
, 0))
758 GetDiskFreeSpaceExA(szPath
, NULL
, &ulBytes
, NULL
);
759 StrFormatByteSize64A(ulBytes
.QuadPart
, psd
->str
.cStr
, MAX_PATH
);
762 case 3: /* free size */
763 _ILSimpleGetText (pidl
, szPath
, MAX_PATH
);
764 if (GetVolumeInformationA(szPath
, NULL
, 0, NULL
, NULL
, NULL
, NULL
, 0))
766 GetDiskFreeSpaceExA(szPath
, &ulBytes
, NULL
, NULL
);
767 StrFormatByteSize64A(ulBytes
.QuadPart
, psd
->str
.cStr
, MAX_PATH
);
777 HRESULT WINAPI
CDrivesFolder::MapColumnToSCID(UINT column
, SHCOLUMNID
* pscid
)
779 FIXME("(%p)\n", this);
783 /************************************************************************
784 * CDrivesFolder::GetClassID
786 HRESULT WINAPI
CDrivesFolder::GetClassID(CLSID
*lpClassId
)
788 TRACE ("(%p)\n", this);
793 *lpClassId
= CLSID_MyComputer
;
797 /************************************************************************
798 * CDrivesFolder::Initialize
800 * NOTES: it makes no sense to change the pidl
802 HRESULT WINAPI
CDrivesFolder::Initialize(LPCITEMIDLIST pidl
)
804 TRACE ("(%p)->(%p)\n", this, pidl
);
807 SHFree((LPVOID
)pidlRoot
);
809 pidlRoot
= ILClone(pidl
);
813 /**************************************************************************
814 * CDrivesFolder::GetCurFolder
816 HRESULT WINAPI
CDrivesFolder::GetCurFolder(LPITEMIDLIST
*pidl
)
818 TRACE("(%p)->(%p)\n", this, pidl
);
823 *pidl
= ILClone(pidlRoot
);