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 class CDrivesFolderEnum
:
43 public CEnumIDListBase
48 HRESULT WINAPI
Initialize(HWND hwndOwner
, DWORD dwFlags
);
49 BOOL
CreateMyCompEnumList(DWORD dwFlags
);
51 BEGIN_COM_MAP(CDrivesFolderEnum
)
52 COM_INTERFACE_ENTRY_IID(IID_IEnumIDList
, IEnumIDList
)
56 /***********************************************************************
57 * IShellFolder [MyComputer] implementation
60 static const shvheader MyComputerSFHeader
[] = {
61 {IDS_SHV_COLUMN1
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 15},
62 {IDS_SHV_COLUMN3
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 10},
63 {IDS_SHV_COLUMN6
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10},
64 {IDS_SHV_COLUMN7
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10},
67 #define MYCOMPUTERSHELLVIEWCOLUMNS 4
69 static const DWORD dwComputerAttributes
=
70 SFGAO_CANRENAME
| SFGAO_CANDELETE
| SFGAO_HASPROPSHEET
| SFGAO_DROPTARGET
|
71 SFGAO_FILESYSANCESTOR
| SFGAO_FOLDER
| SFGAO_HASSUBFOLDER
| SFGAO_CANLINK
;
72 static const DWORD dwControlPanelAttributes
=
73 SFGAO_HASSUBFOLDER
| SFGAO_FOLDER
| SFGAO_CANLINK
;
74 static const DWORD dwDriveAttributes
=
75 SFGAO_HASSUBFOLDER
| SFGAO_FILESYSTEM
| SFGAO_FOLDER
| SFGAO_FILESYSANCESTOR
|
76 SFGAO_DROPTARGET
| SFGAO_HASPROPSHEET
| SFGAO_CANRENAME
| SFGAO_CANLINK
;
78 CDrivesFolderEnum::CDrivesFolderEnum()
82 CDrivesFolderEnum::~CDrivesFolderEnum()
86 HRESULT WINAPI
CDrivesFolderEnum::Initialize(HWND hwndOwner
, DWORD dwFlags
)
88 if (CreateMyCompEnumList(dwFlags
) == FALSE
)
94 /**************************************************************************
95 * CDrivesFolderEnum::CreateMyCompEnumList()
98 BOOL
CDrivesFolderEnum::CreateMyCompEnumList(DWORD dwFlags
)
101 static const WCHAR MyComputer_NameSpaceW
[] = L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\Namespace";
103 TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags
);
105 /* enumerate the folders */
106 if (dwFlags
& SHCONTF_FOLDERS
)
108 WCHAR wszDriveName
[] = {'A', ':', '\\', '\0'};
109 DWORD dwDrivemap
= GetLogicalDrives();
113 while (bRet
&& wszDriveName
[0] <= 'Z')
115 if(dwDrivemap
& 0x00000001L
)
116 bRet
= AddToEnumList(_ILCreateDrive(wszDriveName
));
118 dwDrivemap
= dwDrivemap
>> 1;
121 TRACE("-- (%p)-> enumerate (mycomputer shell extensions)\n", this);
122 for (i
= 0; i
< 2; i
++)
124 if (bRet
&& ERROR_SUCCESS
== RegOpenKeyExW(i
== 0 ? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
,
125 MyComputer_NameSpaceW
, 0, KEY_READ
, &hKey
))
134 dwSize
= sizeof(wszBuf
) / sizeof(wszBuf
[0]);
135 ErrorCode
= RegEnumKeyExW(hKey
, j
, wszBuf
, &dwSize
, 0, NULL
, NULL
, NULL
);
136 if (ERROR_SUCCESS
== ErrorCode
)
138 if (wszBuf
[0] != L
'{')
140 dwSize
= sizeof(wszBuf
);
141 RegGetValueW(hKey
, wszBuf
, NULL
, RRF_RT_REG_SZ
, NULL
, wszBuf
, &dwSize
);
144 /* FIXME: shell extensions - the type should be PT_SHELLEXT (tested) */
145 pidl
= _ILCreateGuidFromStrW(wszBuf
);
147 bRet
= AddToEnumList(pidl
);
149 ERR("Invalid MyComputer namespace extesion: %s\n", wszBuf
);
152 else if (ERROR_NO_MORE_ITEMS
== ErrorCode
)
164 CDrivesFolder::CDrivesFolder()
170 CDrivesFolder::~CDrivesFolder()
172 TRACE ("-- destroying IShellFolder(%p)\n", this);
176 HRESULT WINAPI
CDrivesFolder::FinalConstruct()
179 WCHAR szName
[MAX_PATH
];
180 WCHAR wszMyCompKey
[256];
183 pidlRoot
= _ILCreateMyComputer(); /* my qualified pidl */
184 if (pidlRoot
== NULL
)
185 return E_OUTOFMEMORY
;
187 i
= swprintf(wszMyCompKey
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\");
188 StringFromGUID2(CLSID_MyComputer
, wszMyCompKey
+ i
, sizeof(wszMyCompKey
) / sizeof(wszMyCompKey
[0]) - i
);
189 dwSize
= sizeof(szName
);
190 if (RegGetValueW(HKEY_CURRENT_USER
, wszMyCompKey
,
191 NULL
, RRF_RT_REG_SZ
, NULL
, szName
, &dwSize
) == ERROR_SUCCESS
)
193 sName
= (LPWSTR
)SHAlloc((wcslen(szName
) + 1) * sizeof(WCHAR
));
195 wcscpy(sName
, szName
);
196 TRACE("sName %s\n", debugstr_w(sName
));
201 /**************************************************************************
202 * CDrivesFolder::ParseDisplayName
204 HRESULT WINAPI
CDrivesFolder::ParseDisplayName(HWND hwndOwner
, LPBC pbc
, LPOLESTR lpszDisplayName
,
205 DWORD
* pchEaten
, PIDLIST_RELATIVE
* ppidl
, DWORD
* pdwAttributes
)
207 HRESULT hr
= E_INVALIDARG
;
208 LPCWSTR szNext
= NULL
;
209 WCHAR szElement
[MAX_PATH
];
210 LPITEMIDLIST pidlTemp
= NULL
;
212 TRACE("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n", this,
213 hwndOwner
, pbc
, lpszDisplayName
, debugstr_w (lpszDisplayName
),
214 pchEaten
, ppidl
, pdwAttributes
);
218 *pchEaten
= 0; /* strange but like the original */
220 /* handle CLSID paths */
221 if (lpszDisplayName
[0] == ':' && lpszDisplayName
[1] == ':')
223 return SH_ParseGuidDisplayName(this, hwndOwner
, pbc
, lpszDisplayName
, pchEaten
, ppidl
, pdwAttributes
);
225 /* do we have an absolute path name ? */
226 else if (PathGetDriveNumberW (lpszDisplayName
) >= 0 &&
227 lpszDisplayName
[2] == (WCHAR
) '\\')
229 szNext
= GetNextElementW (lpszDisplayName
, szElement
, MAX_PATH
);
230 /* make drive letter uppercase to enable PIDL comparison */
231 szElement
[0] = toupper(szElement
[0]);
232 pidlTemp
= _ILCreateDrive (szElement
);
235 if (szNext
&& *szNext
)
237 hr
= SHELL32_ParseNextElement (this, hwndOwner
, pbc
, &pidlTemp
,
238 (LPOLESTR
) szNext
, pchEaten
, pdwAttributes
);
243 if (pdwAttributes
&& *pdwAttributes
)
245 if (_ILIsDrive(pidlTemp
))
246 *pdwAttributes
&= dwDriveAttributes
;
247 else if (_ILIsSpecialFolder(pidlTemp
))
248 SHELL32_GetGuidItemAttributes(this, pidlTemp
, pdwAttributes
);
250 ERR("Got an unkown pidl here!\n");
256 TRACE ("(%p)->(-- ret=0x%08x)\n", this, hr
);
261 /**************************************************************************
262 * CDrivesFolder::EnumObjects
264 HRESULT WINAPI
CDrivesFolder::EnumObjects(HWND hwndOwner
, DWORD dwFlags
, LPENUMIDLIST
*ppEnumIDList
)
266 return ShellObjectCreatorInit
<CDrivesFolderEnum
>(hwndOwner
, dwFlags
, IID_IEnumIDList
, ppEnumIDList
);
269 /**************************************************************************
270 * CDrivesFolder::BindToObject
272 HRESULT WINAPI
CDrivesFolder::BindToObject(PCUIDLIST_RELATIVE pidl
, LPBC pbcReserved
, REFIID riid
, LPVOID
*ppvOut
)
274 TRACE("(%p)->(pidl=%p,%p,%s,%p)\n", this,
275 pidl
, pbcReserved
, shdebugstr_guid(&riid
), ppvOut
);
277 if (_ILIsSpecialFolder(pidl
))
278 return SHELL32_BindToGuidItem(pidlRoot
, pidl
, pbcReserved
, riid
, ppvOut
);
280 return SHELL32_BindToFS(pidlRoot
, NULL
, pidl
, riid
, ppvOut
);
283 /**************************************************************************
284 * CDrivesFolder::BindToStorage
286 HRESULT WINAPI
CDrivesFolder::BindToStorage(PCUIDLIST_RELATIVE pidl
, LPBC pbcReserved
, REFIID riid
, LPVOID
*ppvOut
)
288 FIXME("(%p)->(pidl=%p,%p,%s,%p) stub\n", this,
289 pidl
, pbcReserved
, shdebugstr_guid (&riid
), ppvOut
);
295 /**************************************************************************
296 * CDrivesFolder::CompareIDs
299 HRESULT WINAPI
CDrivesFolder::CompareIDs(LPARAM lParam
, PCUIDLIST_RELATIVE pidl1
, PCUIDLIST_RELATIVE pidl2
)
301 if (_ILIsSpecialFolder(pidl1
) || _ILIsSpecialFolder(pidl2
))
302 return SHELL32_CompareGuidItems(this, lParam
, pidl1
, pidl2
);
304 if (!_ILIsDrive(pidl1
) || !_ILIsDrive(pidl2
) || LOWORD(lParam
) >= MYCOMPUTERSHELLVIEWCOLUMNS
)
307 CHAR
* pszDrive1
= _ILGetDataPointer(pidl1
)->u
.drive
.szDriveName
;
308 CHAR
* pszDrive2
= _ILGetDataPointer(pidl2
)->u
.drive
.szDriveName
;
311 switch(LOWORD(lParam
))
315 result
= stricmp(pszDrive1
, pszDrive2
);
316 return MAKE_COMPARE_HRESULT(result
);
320 return SHELL32_CompareDetails(this, lParam
, pidl1
, pidl2
);
323 case 3: /* Size Available */
325 ULARGE_INTEGER Drive1Available
, Drive1Total
, Drive2Available
, Drive2Total
;
327 if (GetVolumeInformationA(pszDrive1
, NULL
, 0, NULL
, NULL
, NULL
, NULL
, 0))
328 GetDiskFreeSpaceExA(pszDrive1
, &Drive1Available
, &Drive1Total
, NULL
);
330 Drive1Available
.QuadPart
= Drive1Total
.QuadPart
= 0;
332 if (GetVolumeInformationA(pszDrive2
, NULL
, 0, NULL
, NULL
, NULL
, NULL
, 0))
333 GetDiskFreeSpaceExA(pszDrive2
, &Drive2Available
, &Drive2Total
, NULL
);
335 Drive2Available
.QuadPart
= Drive2Total
.QuadPart
= 0;
338 if (lParam
== 2) /* Size */
339 Diff
.QuadPart
= Drive1Total
.QuadPart
- Drive2Total
.QuadPart
;
340 else /* Size available */
341 Diff
.QuadPart
= Drive1Available
.QuadPart
- Drive2Available
.QuadPart
;
343 return MAKE_COMPARE_HRESULT(Diff
.QuadPart
);
349 /**************************************************************************
350 * CDrivesFolder::CreateViewObject
352 HRESULT WINAPI
CDrivesFolder::CreateViewObject(HWND hwndOwner
, REFIID riid
, LPVOID
* ppvOut
)
354 CComPtr
<IShellView
> pShellView
;
355 HRESULT hr
= E_INVALIDARG
;
357 TRACE("(%p)->(hwnd=%p,%s,%p)\n", this,
358 hwndOwner
, shdebugstr_guid (&riid
), ppvOut
);
365 if (IsEqualIID(riid
, IID_IDropTarget
))
367 WARN("IDropTarget not implemented\n");
370 else if (IsEqualIID(riid
, IID_IContextMenu
))
372 WARN("IContextMenu not implemented\n");
375 else if (IsEqualIID(riid
, IID_IShellView
))
377 hr
= CDefView_Constructor(this, riid
, ppvOut
);
379 TRACE ("-- (%p)->(interface=%p)\n", this, ppvOut
);
383 static BOOL
_ILIsControlPanel(LPCITEMIDLIST pidl
)
385 GUID
*guid
= _ILGetGUIDPointer(pidl
);
387 TRACE("(%p)\n", pidl
);
390 return IsEqualIID(*guid
, CLSID_ControlPanel
);
394 /**************************************************************************
395 * CDrivesFolder::GetAttributesOf
397 HRESULT WINAPI
CDrivesFolder::GetAttributesOf(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, DWORD
* rgfInOut
)
399 TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
400 this, cidl
, apidl
, rgfInOut
, rgfInOut
? *rgfInOut
: 0);
408 /* FIXME: always add SFGAO_CANLINK */
410 *rgfInOut
&= dwComputerAttributes
;
413 for (UINT i
= 0; i
< cidl
; ++i
)
415 if (_ILIsDrive(apidl
[i
]))
416 *rgfInOut
&= dwDriveAttributes
;
417 else if (_ILIsControlPanel(apidl
[i
]))
418 *rgfInOut
&= dwControlPanelAttributes
;
419 else if (_ILIsSpecialFolder(*apidl
))
420 SHELL32_GetGuidItemAttributes(this, apidl
[i
], rgfInOut
);
422 ERR("Got unknown pidl type!\n");
426 /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
427 *rgfInOut
&= ~SFGAO_VALIDATE
;
429 TRACE ("-- result=0x%08x\n", *rgfInOut
);
433 /**************************************************************************
434 * CDrivesFolder::GetUIObjectOf
437 * hwndOwner [in] Parent window for any output
438 * cidl [in] array size
439 * apidl [in] simple pidl array
440 * riid [in] Requested Interface
441 * prgfInOut [ ] reserved
442 * ppvObject [out] Resulting Interface
445 HRESULT WINAPI
CDrivesFolder::GetUIObjectOf(HWND hwndOwner
,
446 UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
,
447 REFIID riid
, UINT
*prgfInOut
, LPVOID
*ppvOut
)
450 IUnknown
*pObj
= NULL
;
451 HRESULT hr
= E_INVALIDARG
;
453 TRACE("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n", this,
454 hwndOwner
, cidl
, apidl
, shdebugstr_guid (&riid
), prgfInOut
, ppvOut
);
461 if (IsEqualIID (riid
, IID_IContextMenu
) && (cidl
>= 1))
463 hr
= CDefFolderMenu_Create2(pidlRoot
, hwndOwner
, cidl
, apidl
, (IShellFolder
*)this, NULL
, 0, NULL
, (IContextMenu
**)&pObj
);
465 else if (IsEqualIID (riid
, IID_IDataObject
) && (cidl
>= 1))
467 hr
= IDataObject_Constructor (hwndOwner
,
468 pidlRoot
, apidl
, cidl
, (IDataObject
**)&pObj
);
470 else if (IsEqualIID (riid
, IID_IExtractIconA
) && (cidl
== 1))
472 pidl
= ILCombine (pidlRoot
, apidl
[0]);
473 pObj
= IExtractIconA_Constructor (pidl
);
477 else if (IsEqualIID (riid
, IID_IExtractIconW
) && (cidl
== 1))
479 pidl
= ILCombine (pidlRoot
, apidl
[0]);
480 pObj
= IExtractIconW_Constructor (pidl
);
484 else if (IsEqualIID (riid
, IID_IDropTarget
) && (cidl
>= 1))
486 IDropTarget
* pDt
= NULL
;
487 hr
= this->QueryInterface(IID_PPV_ARG(IDropTarget
, &pDt
));
490 else if ((IsEqualIID(riid
, IID_IShellLinkW
) ||
491 IsEqualIID(riid
, IID_IShellLinkA
)) && (cidl
== 1))
493 pidl
= ILCombine (pidlRoot
, apidl
[0]);
494 hr
= IShellLink_ConstructFromFile(NULL
, riid
, pidl
, (LPVOID
*) &pObj
);
500 if (SUCCEEDED(hr
) && !pObj
)
504 TRACE ("(%p)->hr=0x%08x\n", this, hr
);
508 /**************************************************************************
509 * CDrivesFolder::GetDisplayNameOf
511 HRESULT WINAPI
CDrivesFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl
, DWORD dwFlags
, LPSTRRET strRet
)
516 TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl
, dwFlags
, strRet
);
522 if (!_ILIsPidlSimple (pidl
))
524 return SHELL32_GetDisplayNameOfChild(this, pidl
, dwFlags
, strRet
);
526 else if (!_ILIsDesktop(pidl
) && _ILIsSpecialFolder(pidl
))
528 return SHELL32_GetDisplayNameOfGUIDItem(this, L
"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", pidl
, dwFlags
, strRet
);
530 else if (pidl
->mkid
.cb
&& !_ILIsDrive(pidl
))
532 ERR("Wrong pidl type\n");
536 pszPath
= (LPWSTR
)CoTaskMemAlloc((MAX_PATH
+ 1) * sizeof(WCHAR
));
538 return E_OUTOFMEMORY
;
544 /* parsing name like ::{...} */
547 SHELL32_GUIDToStringW(CLSID_MyComputer
, &pszPath
[2]);
551 _ILSimpleGetTextW(pidl
, pszPath
, MAX_PATH
); /* append my own path */
552 /* long view "lw_name (C:)" */
553 if (!(dwFlags
& SHGDN_FORPARSING
))
555 WCHAR wszDrive
[18] = {0};
556 DWORD dwVolumeSerialNumber
, dwMaximumComponentLength
, dwFileSystemFlags
;
557 static const WCHAR wszOpenBracket
[] = {' ', '(', 0};
558 static const WCHAR wszCloseBracket
[] = {')', 0};
560 lstrcpynW(wszDrive
, pszPath
, 4);
562 GetVolumeInformationW(wszDrive
, pszPath
,
564 &dwVolumeSerialNumber
,
565 &dwMaximumComponentLength
, &dwFileSystemFlags
, NULL
, 0);
566 pszPath
[MAX_PATH
-1] = L
'\0';
567 if (!wcslen(pszPath
))
569 UINT DriveType
, ResourceId
;
570 DriveType
= GetDriveTypeW(wszDrive
);
574 ResourceId
= IDS_DRIVE_FIXED
;
577 ResourceId
= IDS_DRIVE_NETWORK
;
580 ResourceId
= IDS_DRIVE_CDROM
;
587 dwFileSystemFlags
= LoadStringW(shell32_hInstance
, ResourceId
, pszPath
, MAX_PATH
);
588 if (dwFileSystemFlags
> MAX_PATH
- 7)
589 pszPath
[MAX_PATH
-7] = L
'\0';
592 wcscat (pszPath
, wszOpenBracket
);
594 wcscat (pszPath
, wszDrive
);
595 wcscat (pszPath
, wszCloseBracket
);
601 strRet
->uType
= STRRET_WSTR
;
602 strRet
->pOleStr
= pszPath
;
605 CoTaskMemFree(pszPath
);
607 TRACE("-- (%p)->(%s)\n", this, strRet
->uType
== STRRET_CSTR
? strRet
->cStr
: debugstr_w(strRet
->pOleStr
));
611 /**************************************************************************
612 * CDrivesFolder::SetNameOf
613 * Changes the name of a file object or subfolder, possibly changing its item
614 * identifier in the process.
617 * hwndOwner [in] Owner window for output
618 * pidl [in] simple pidl of item to change
619 * lpszName [in] the items new display name
620 * dwFlags [in] SHGNO formatting flags
621 * ppidlOut [out] simple pidl returned
623 HRESULT WINAPI
CDrivesFolder::SetNameOf(HWND hwndOwner
, PCUITEMID_CHILD pidl
,
624 LPCOLESTR lpName
, DWORD dwFlags
, PITEMID_CHILD
*pPidlOut
)
628 if (_ILIsDrive(pidl
))
630 if (_ILSimpleGetTextW(pidl
, szName
, _countof(szName
)))
631 SetVolumeLabelW(szName
, lpName
);
633 *pPidlOut
= _ILCreateDrive(szName
);
637 return SHELL32_SetNameOfGuidItem(pidl
, lpName
, dwFlags
, pPidlOut
);
640 HRESULT WINAPI
CDrivesFolder::GetDefaultSearchGUID(GUID
* pguid
)
642 FIXME ("(%p)\n", this);
646 HRESULT WINAPI
CDrivesFolder::EnumSearches(IEnumExtraSearch
** ppenum
)
648 FIXME ("(%p)\n", this);
652 HRESULT WINAPI
CDrivesFolder::GetDefaultColumn (DWORD dwRes
, ULONG
*pSort
, ULONG
*pDisplay
)
654 TRACE ("(%p)\n", this);
663 HRESULT WINAPI
CDrivesFolder::GetDefaultColumnState(UINT iColumn
, DWORD
* pcsFlags
)
665 TRACE ("(%p)\n", this);
667 if (!pcsFlags
|| iColumn
>= MYCOMPUTERSHELLVIEWCOLUMNS
)
669 *pcsFlags
= MyComputerSFHeader
[iColumn
].pcsFlags
;
673 HRESULT WINAPI
CDrivesFolder::GetDetailsEx(PCUITEMID_CHILD pidl
, const SHCOLUMNID
* pscid
, VARIANT
* pv
)
675 FIXME ("(%p)\n", this);
679 /* FIXME: drive size >4GB is rolling over */
680 HRESULT WINAPI
CDrivesFolder::GetDetailsOf(PCUITEMID_CHILD pidl
, UINT iColumn
, SHELLDETAILS
*psd
)
684 TRACE ("(%p)->(%p %i %p)\n", this, pidl
, iColumn
, psd
);
686 if (!psd
|| iColumn
>= MYCOMPUTERSHELLVIEWCOLUMNS
)
691 psd
->fmt
= MyComputerSFHeader
[iColumn
].fmt
;
692 psd
->cxChar
= MyComputerSFHeader
[iColumn
].cxChar
;
693 psd
->str
.uType
= STRRET_CSTR
;
694 LoadStringA(shell32_hInstance
, MyComputerSFHeader
[iColumn
].colnameid
,
695 psd
->str
.cStr
, MAX_PATH
);
698 else if (_ILIsSpecialFolder(pidl
))
700 return SHELL32_GetDetailsOfGuidItem(this, pidl
, iColumn
, psd
);
704 char szPath
[MAX_PATH
];
705 ULARGE_INTEGER ulBytes
;
707 psd
->str
.cStr
[0] = 0x00;
708 psd
->str
.uType
= STRRET_CSTR
;
712 hr
= GetDisplayNameOf(pidl
, SHGDN_NORMAL
| SHGDN_INFOLDER
, &psd
->str
);
715 _ILGetFileType(pidl
, psd
->str
.cStr
, MAX_PATH
);
717 case 2: /* total size */
718 _ILSimpleGetText (pidl
, szPath
, MAX_PATH
);
719 if (GetVolumeInformationA(szPath
, NULL
, 0, NULL
, NULL
, NULL
, NULL
, 0))
721 GetDiskFreeSpaceExA(szPath
, NULL
, &ulBytes
, NULL
);
722 StrFormatByteSize64A(ulBytes
.QuadPart
, psd
->str
.cStr
, MAX_PATH
);
725 case 3: /* free size */
726 _ILSimpleGetText (pidl
, szPath
, MAX_PATH
);
727 if (GetVolumeInformationA(szPath
, NULL
, 0, NULL
, NULL
, NULL
, NULL
, 0))
729 GetDiskFreeSpaceExA(szPath
, &ulBytes
, NULL
, NULL
);
730 StrFormatByteSize64A(ulBytes
.QuadPart
, psd
->str
.cStr
, MAX_PATH
);
740 HRESULT WINAPI
CDrivesFolder::MapColumnToSCID(UINT column
, SHCOLUMNID
* pscid
)
742 FIXME("(%p)\n", this);
746 /************************************************************************
747 * CDrivesFolder::GetClassID
749 HRESULT WINAPI
CDrivesFolder::GetClassID(CLSID
*lpClassId
)
751 TRACE ("(%p)\n", this);
756 *lpClassId
= CLSID_MyComputer
;
760 /************************************************************************
761 * CDrivesFolder::Initialize
763 * NOTES: it makes no sense to change the pidl
765 HRESULT WINAPI
CDrivesFolder::Initialize(LPCITEMIDLIST pidl
)
767 TRACE ("(%p)->(%p)\n", this, pidl
);
770 SHFree((LPVOID
)pidlRoot
);
772 pidlRoot
= ILClone(pidl
);
776 /**************************************************************************
777 * CDrivesFolder::GetCurFolder
779 HRESULT WINAPI
CDrivesFolder::GetCurFolder(LPITEMIDLIST
*pidl
)
781 TRACE("(%p)->(%p)\n", this, pidl
);
786 *pidl
= ILClone(pidlRoot
);